/* gpbrqgen.p - Browse Query Generator                                        */
/* Copyright 1986-2003 QAD Inc., Carpinteria, CA, USA.                        */
/* All rights reserved worldwide.  This is an unpublished work.               */
/* $Revision: 1.71.1.5 $                                                      */
/*V8:ConvertMode=NoConvert                                                    */
/*********************************** History **********************************
 *  Revision: 8.5    Created: 04/24/97  *J1PW*  By: Allan Doane
 *  Revision: 8.5   Modified: 06/06/97  *J1SN*  By: Allan Doane
 *  Revision: 8.5   Modified: 06/10/97  *J1SZ*  By: Jean Miller
 *  Revision: 8.5   Modified: 06/10/97  *J1SS*  By: Bill Pedersen
 *  Revision: 8.5   Modified: 06/16/97  *J1TF*  By: Bill Pedersen
 *  Revision: 8.5   Modified: 06/29/97  *J1VL*  By: Bill Pedersen
 *  Revision: 8.5   Modified: 07/15/97  *J1VP*  By: Jean Miller
 *  Revision: 8.5   Modified: 07/21/97  *J1X6*  By: Bill Pedersen
 *  Revision: 8.5   Modified: 07/24/97  *J1XN*  By: Bill Pedersen
 *  Revision: 8.5   Modified: 08/14/97  *J1ZZ*  By: Jean Miller
 *  Revision: 8.5   Modified: 10/29/97  *J24P*  By: Mark B. Smith
 *  Revision: 8.5   Modified: 11/11/97  *J25S*  By: Mark B. Smith
 *  Revision: 8.5   Modified: 01/19/98  *J2BG*  By: Jean Miller
 *  Revision: 8.5   Modified: 03/09/98  *J2G8*  By: Jean Miller
 *  Revision: 8.5   Modified: 02/24/98  *J2GQ*  By: Mark B. Smith
 *  Revision: 8.5   Modified: 04/21/98  *J2KZ*  By: Mark B. Smith
 *  Revision: 8.5   Modified: 04/29/98  *J2JB*  By: Suhas Bhargave
 *  Revision: 8.5   Modified: 05/13/98  *K1Q0*  By: Mark B. Smith
 *  Revision: 8.6   Modified: 05/20/98  *K1Q4*  By: Alfred Tan
 *  Revision: 8.5   Modified: 05/18/98  *J2MT*  By: Mark B. Smith
 *  Revision: 8.5   Modified: 07/07/98  *J2RQ*  By: Mark B. Smith
 *  Revision: 9.0   Modified: 01/08/99  *M04S*  By: Jean P. Miller
 *  Revision: 8.5   Modified: 01/12/99  *J38B*  By: Raphael T.
 *  Revision: 9.0   Modified: 01/29/99  *M06Y*  By: Doug Norton
 *  Revision: 8.5   Modified: 02/11/99  *J39P*  By: John Corda
 *  Revision: 9.0   Modified: 03/13/99  *M0BD*  BY: Alfred Tan
 *  Revision: 9.0   Modified: 03/25/99  *J3C3*  By: John Corda
 *  Revision: 9.0   Modified: 04/06/99  *J3CQ*  By: A. Philips
 *  Revision: 9.0   Modified: 06/24/99  *J3HB*  By: John Corda
 *  Revision: 9.1   Modified: 07/28/99  *J3JX*  By: J. Fernando
 *  Revision: 9.1   Modified: 09/22/99  *K231*  By: Jean Miller
 *  Revision: 9.1   Modified: 10/01/99  *N014*  By: Robin McCarthy
 *  Revision: 9.1   Modified: 10/06/99  *N03X*  By: John Corda
 *  Revision: 9.1   Modified: 10/25/99  *N04T*  By: Jean Miller
 *  Revision: 9.1   Modified: 03/06/00  *N082*  By: Jean Miller
 *  Revision: 9.1   Modified: 07/31/00  *N0H7*  By: Jean Miller
 *  Revision: 9.1   Modified: 08/14/00  *N0KV*  By: Viswanathan M
 *  Revision: 9.1   Modified: 05/05/01  *N0YG*  By: Viswanathan M             */
/*  Revision: 1.55      By: Katie Hilbert   DATE: 10/11/01   ECO: *P028*      */
/*  Revision: 1.57      By: Falguni Dalal   DATE: 10/18/01   ECO: *M1M8*      */
/*  Revision: 1.58      By: Katie Hilbert   DATE: 11/03/01   ECO: *P00B*      */
/*  Revision: 1.60      By: Jean Miller     DATE: 11/27/01   ECO: *P032*      */
/*  Revision: 1.62      By: Jean Miller     DATE: 11/30/01   ECO: *P031*      */
/*  Revision: 1.63      By: John Pison      DATE: 02/07/01   ECO: *N18V*      */
/*  Revision: 1.67      By: Jean Miller     DATE: 03/19/02   ECO: *N1BW*      */
/*  Revision: 1.68      By: Jean Miller     DATE: 05/01/02   ECO: *N1CS*      */
/*  Revision: 1.70      By: Katie Hilbert   DATE: 06/11/02   ECO: *P088*      */
/*  Revision: 1.71      By: Manish Dani     DATE: 03/06/03   ECO: *N28W*      */
/*  Revision: 1.71.1.2  By: Jean Miller     DATE: 08/26/03   ECO: *P11M*      */
/*  Revision: 1.71.1.4  By: Manjusha Inglay DATE: 09/25/03   ECO: *N2LC*      */
/* $Revision: 1.71.1.5 $    By: Vinod Nair       DATE: 12/22/03   ECO: *P1GJ*      */
/******************************************************************************/
/******************************************************************************/
/* All patch markers and commented out code have been removed from the source */
/* code below. For all future modifications to this file, any code which is   */
/* no longer required should be deleted and no in-line patch markers should   */
/* be added.  The ECO marker should only be included in the Revision History. */
/******************************************************************************/
{mfdeclre.i}
{mf1.i}
{gplabel.i}
/*LOCAL VARIABLE DEFINITIONS*/
define variable l-subdirrcode-found  as logical no-undo.
define variable l-localpcode-found   as logical no-undo.
define variable l-localrcode-found   as logical no-undo.
define variable l_length             as integer no-undo.
define variable c-vuf-label   like vuf_det.vuf_label    no-undo.
define variable c-vuf-format  like vuf_det.vuf_format   no-undo.
define variable c-brwf-label  like brwf_det.brwf_label  no-undo.
define variable c-brwf-format like brwf_det.brwf_format no-undo.
define variable c-brw-desc    like brw_mstr.brw_desc    no-undo.
define variable c-fil-frs      as character no-undo.
define variable c-fil-tos      as character no-undo.
define variable c-version      as character no-undo.
define variable c-srch-msg     as character no-undo.
define variable i              as integer   no-undo.
define variable filter-logic   as character extent 5 no-undo.
/*PREPROCESSOR DEFINITIONS*/
&SCOPED-DEFINE CI-DELIM "`"
&SCOPED-DEFINE CI-LABEL 1
&SCOPED-DEFINE CI-DATA-TYPE 2
&SCOPED-DEFINE CI-FORMAT 3
&SCOPED-DEFINE CI-NAME 4
&SCOPED-DEFINE CI-COLUMN-LABEL 5
&SCOPED-DEFINE COL-DELIM "|"
{gpbrwtt.i &new=new}
/* Temp table to hold names of p-code and r-code files generated */
define temp-table tt-file no-undo
    field tt-browse    as character
    field tt-filename  as character
    field tt-rcode     as character
    index tt-filename is unique primary
          tt-browse
          tt-filename.
on find of vuf_det do:
    c-vuf-label = getTermLabel(vuf_det.vuf_label, 45).
    if vuf_det.vuf_datatype = 'logical' then
       c-vuf-format = getTermLabel(vuf_det.vuf_format, 45).
    else
       c-vuf-format = vuf_det.vuf_format.
end.
on find of brwf_det do:
   l_length = if brwf__qadc01 <> "" then
                 integer(brwf__qadc01)
              else
                 45.
   c-brwf-label = getTermLabel(brwf_det.brwf_label, l_length).
   if brwf_det.brwf_datatype = 'logical' then
      c-brwf-format = getTermLabel(brwf_det.brwf_format, 45).
   else
      c-brwf-format = brwf_det.brwf_format.
end.
on find of brw_mstr do:
   c-brw-desc = getTermLabel(brw_mstr.brw_desc, 45).
end.
/* ***************************  Main Block  *************************** */
/* Scope record buffer to entire procedure */
if false then do:
  for first tt-browse-mstr no-lock:
  end.
end.
if not session:batch-mode then
   if progress = "RUN-TIME" then do:
      /* Must be running query-level Progress, contact Sys Administrator */
      {pxmsg.i &MSGNUM=1809 &ERRORLEVEL=4}
       &IF "{&WINDOW-SYSTEM}" = "TTY" &THEN
          pause.
       &ENDIF
       quit.
   end.
this-procedure:private-data = "BROWSEGENERATOR".
/* Get the version of MFG/PRO being used*/
{gprun.i ""gpgetver.p"" "(input "3",output c-version)"}
/* Get the standard search message for Browses and Lookups*/
{gprun.i 'gpmsgmst.p'
   "(input  global_user_lang,
     input  1859,
     output i,
     output c-srch-msg)"}
/* **********************  Internal Procedures  *********************** */
PROCEDURE activate-browse :
/*------------------------------------------------------------------------------
  Purpose:     To activate the browse ui
  Parameters:  
  Notes:
------------------------------------------------------------------------------*/
   define variable l-error    as logical   no-undo.
   define variable c-br-name  as character no-undo.
   define variable h-br-hdl   as handle    no-undo.
   assign c-br-name = tt-browse-mstr.tt-br-ui-name.
   if index(tt-browse-mstr.tt-browse, "zz9") > 0 then do:
      run create-browse-ui
         (input tt-browse,
          input "").  /* no eco */
      run value(tt-br-ui-name) persistent set h-br-hdl.
   end.
   else do:
      {gprun.i "c-br-name" " " "persistent set h-br-hdl"}
   end.
   assign
      h-br-hdl:private-data = c-br-name
      tt-br-hdl = h-br-hdl.
END PROCEDURE.
PROCEDURE activate-printer-graph :
/*------------------------------------------------------------------------------
  Purpose:     To get a graph ui program going
  Parameters:  
  Notes:
------------------------------------------------------------------------------*/
   define input parameter activate-type as character no-undo.
   define variable l-error    as logical   no-undo.
   define variable c-ui-name  as character no-undo.
   define variable h-ui-hdl   as handle    no-undo.
   if activate-type = "GRAPH" then
      c-ui-name = tt-browse-mstr.tt-gr-ui-name.
   else if activate-type = "PRINTER" then
      c-ui-name = tt-browse-mstr.tt-pr-ui-name.
   if l-localrcode-found then do: /* if it already exists locally, run it */
      run value(c-ui-name) persistent set h-ui-hdl.
   end.
   else do:
      run compile-pgm
         (input c-ui-name,
          output l-error).
      if not l-error then do:
         run value(c-ui-name) persistent set h-ui-hdl.
      end.
   end.
   if activate-type = "GRAPH" then
      assign tt-gr-hdl = h-ui-hdl.
   else if activate-type = "PRINTER" then
      assign tt-pr-hdl = h-ui-hdl.
END PROCEDURE.
PROCEDURE activate-lookup :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  
  Notes:
------------------------------------------------------------------------------*/
   define variable l-error    as logical   no-undo.
   define variable c-ui-name  as character no-undo.
   define variable h-ui-hdl   as handle    no-undo.
   assign c-ui-name = tt-browse-mstr.tt-lu-ui-name.
   if index(tt-browse-mstr.tt-browse, "zz9") > 0 then do:
      run create-lookup-ui
         (input tt-browse,
          input "").  /* no eco */
      do on error undo, leave:
         run value(c-ui-name)
            (input THIS-PROCEDURE).
      end.
   end.
   else do on error undo, leave:
      {gprun.i "c-ui-name" "(input THIS-PROCEDURE)" }
   end.
   if available tt-browse-mstr then do:
      if valid-handle(tt-browse-mstr.tt-ql-hdl) then do:
         run close-query in tt-ql-hdl.
         delete procedure tt-ql-hdl.
         assign tt-ql-hdl = ?.
      end.
      run remove-file
         (input tt-lookup-qry-name).
   end.
END PROCEDURE.
PROCEDURE activate-query :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-query-name as character no-undo.
   define output parameter p-query-hdl as handle    no-undo.
   define variable l-error as logical no-undo.
   run compile-pgm
      (input p-query-name,
       output l-error).
   if not l-error then do:
      run value(p-query-name) persistent set p-query-hdl.
   end.
   else do:
      /*Browse Definition is invalid, correct in Browse Maintenance*/
      {pxmsg.i &MSGNUM=1885 &ERRORLEVEL=4}
      &IF "{&WINDOW-SYSTEM}" = "TTY" &THEN
         pause.
      &ENDIF
   end.
END PROCEDURE.
PROCEDURE activate-ui :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  input p-ui-type: character: launch which type of ui
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-ui-type as character no-undo.
   case p-ui-type:
      when ("POWER") then do:
         run activate-browse .
      end.
      when ("LOOKUP") then do:
         run activate-lookup .
      end.
      when ("PRINTER") then do:
         run activate-printer-graph
            (input p-ui-type).
      end.
      when ("GRAPH") then do:
         run activate-printer-graph
            (input p-ui-type).
      end.
   end case.
END PROCEDURE.
PROCEDURE build-filter-expression :
/*------------------------------------------------------------------------------
  Purpose:     Builds the filter expression for a given table.
  Parameters:  input p-table: character: name of table being filtered
               output p-flt-expr: character: full filter expression for table
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-table     as character no-undo.
   define output parameter p-flt-expr as character no-undo.
   define variable c-val-fr as character no-undo.
   define variable c-val-to as character no-undo.
   for each tt-browse-field of tt-browse-mstr
      where (tt-seq < 11)
        and (tt-table-name = p-table):
      /*Change delimiter to be more standard with other OBCM-1 pgms*/
      assign
         c-val-fr = entry(tt-seq, c-fil-frs, chr(2))
         c-val-to = entry(tt-seq, c-fil-tos, chr(2)).
      run build-sub-expression
         (input c-val-fr,
          input if tt-table-name = "" then tt-expression
                else (tt-table-name + "." + tt-field-name),
          input tt-datatype,
          input "FROM",
          input-output p-flt-expr).
      run build-sub-expression
         (input c-val-to,
          input if tt-table-name = "" then tt-expression
                else (tt-table-name + "." + tt-field-name),
          input tt-datatype,
          input "TO",
          input-output p-flt-expr).
   end. /* for each */
END PROCEDURE.
PROCEDURE build-sub-expression :
/*------------------------------------------------------------------------------
  Purpose:     Builds the sub expression for filter value
  Parameters:  input p-val      : character: filter value
               input p-field    : character: name of field for expression
               input p-from-to  : character: "FROM" or "TO"
               input-output
                     p-flt-expr : character: accumulating filter expression
  Notes:
 -----------------------------------------------------------------------------*/
   define input parameter p-val             as character no-undo.
   define input parameter p-field           as character no-undo.
   define input parameter p-datatype        as character no-undo.
   define input parameter p-from-to         as character no-undo.
   define input-output parameter p-flt-expr as character no-undo.
   define variable c-sub-expr  as character no-undo.
   define variable c-relop     as character no-undo.
   define variable match-begin as character initial " MATCHES " no-undo.
   define variable counter     as integer   initial 0 no-undo.
   define variable temp-val    as character no-undo.
   define variable c-temp-date as date      no-undo.
   if p-val <> "" then do:
      counter = index(p-val, "*").
      /* TO ALLOW ENTRY OF DATES WITH DIFFERENT STARTUP FORMATS */
      if  p-datatype           = "DATE":U
      and session:date-format <> "MDY"
      then do:

         assign
            c-temp-date = date(p-val)  no-error.

         if {gpdate.v c-temp-date}
         then
            p-val = trim(string(month(date(p-val))) + "/" +
                         string(day(date(p-val)))   + "/" +
                         string(year(date(p-val)))).

      end.  /* IF  p-datatype = "DATE":U ... */

      if p-datatype = "CHARACTER" then do:
         if index(p-val, "*") > 0 and
            length(p-val, "CHARACTER") > 1
         then do:
            /*IF WILDCARD IS LAST CHARACTER THEN BEGINS LOGIC  **J2RQ*/
            if counter = length(p-val, "CHARACTER") then do:
               assign
                  match-begin = " BEGINS "
                  /*REMOVE WILDCARD FOR BEGINS LOGIC*/
                  overlay(p-val,counter,1) = " ".
            end.
            /*BEGINS LOGIC IS BLANK SPACE SENSITIVE*/
            p-val = trim(p-val).
         end.  /*if index(p-val, "*") > 0 and*/
      end.  /*if p-datatype = "CHARACTER"*/
      assign
         c-relop    = if counter > 0 then match-begin
                     else (if p-from-to = "FROM" then " >= "
                           else " <= ").
      if p-datatype = "CHARACTER" then
         /* The below code adds Tildes to the filter expression */
         /* containing double quotes to suppress the special    */
         /* meaning of double quotes                            */
         assign
            p-val = replace(p-val,'"','~~~~"')
            p-val = chr(34) + p-val + chr(34).
      assign
         c-sub-expr = "(" + p-field + c-relop + p-val + ")"
         p-flt-expr = p-flt-expr + (if p-flt-expr = "" then ""
                                    else " and ") +
                      c-sub-expr.
   end. /* if p-val <> "" */
END PROCEDURE.
PROCEDURE can-use-field-list :
/*------------------------------------------------------------------------------
  Purpose:     Determines if this browse can take advantage of field lists
  Parameters:  input p-browse-id: character: browse id
               output p-can-use: logical: Yes = can use; No = cannot use them
  Notes:       This routine looks for local variables for the specified browse.
               If a local variable is found, it is assumed that it probably
               contains a complex expression which would preclude the use of
               field lists.  Also, Progress must be version 8 or greater.
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   define output parameter p-can-use  as logical   no-undo.
   run establish-context
      (input p-browse-id).
   /* Look for local variables (ie fields with no table)*/
   for first tt-browse-field of tt-browse-mstr no-lock
      where tt-browse-field.tt-table-name = "":
   end.
   assign
      p-can-use = (not available(tt-browse-field)) and proversion > "8".
END PROCEDURE.
PROCEDURE cleanup-expression :
/*------------------------------------------------------------------------------
  Purpose:     Strip out CR and LF chars from user-entered expressions
               which may contain them.
  Parameters:  p-i-str - the string that may contain CR and/or LF chars
               p-o-str - the string devoid of any CR and LF chars
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-i-str  as character no-undo.
   define output parameter p-o-str as character no-undo.
   define variable i as integer no-undo.
   assign
      p-o-str = p-i-str
      i = index(p-o-str, "~n").
   do while i > 0:
      assign
         substring(p-o-str, i, 1) = " "
         i = index(p-o-str, "~n").
   end.
END PROCEDURE.
PROCEDURE compile-pgm :
/*------------------------------------------------------------------------------
  Purpose:     Compiles the designated program and to handle any errors
  Parameters:  p-name: name of file to compile
               p-error: error indicator
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-name as character no-undo.
   define output parameter p-error as logical no-undo.
   compile value(p-name) save no-error.
   assign
      p-error = compiler:error.
END PROCEDURE.
PROCEDURE construct-browse :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  input p-browse-id: character: name of browse create
               input p-sort-by  : integer;   column to sort query by
               input p-sort-dir : integer;   direction of sort
                                             1 = ascending, 2 = desc.
  Notes:       This is called to start up a new browse.
               It manages (or delegates) the different functions
               required to get a new browse off the ground.
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character no-undo.
   define input  parameter p-sort-by   as integer   no-undo.
   define input  parameter p-sort-dir  as integer   no-undo.
   define output parameter p-browse    as handle    no-undo.
   define output parameter p-query     as handle    no-undo.
   run establish-context
      (input p-browse-id).
   run generate-unfiltered-query
      (input p-browse-id,
       input p-sort-by,
       input p-sort-dir = 2,
       output p-query).
   run create-browse.
   assign
      p-browse = tt-browse-mstr.tt-br-hdl.
END PROCEDURE.
PROCEDURE construct-graph :
/*------------------------------------------------------------------------------
  Purpose:     To start up a browse graph task.
  Parameters:  input  p-browse-id: character: name of browse create
               input  p-sort-by  : integer;   column to sort query by
               input  p-filter   : integer;   filter type
                                   1 = Unfiltered, 2 = Filtered.
               output p-graph    : handle;    handle of Graph UI
  Notes:       It will generate a Graph UI if it has to, but first,
               it will see if
               a browse is already using a Graph and will use that one
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character no-undo.
   define input  parameter p-sort-by   as integer   no-undo.
   define input  parameter p-filter    as integer   no-undo.
   define output parameter p-graph     as handle    no-undo.
   define variable c-query-type as character no-undo.
   assign c-query-type = (if p-filter = 1 then "UNFILT" else "FILT").
   run establish-context
      (input p-browse-id).
   run look-for-code
      (input "GRAPH",
       output l-localrcode-found,
       output l-localpcode-found).
   if not l-localrcode-found and
      not l-localpcode-found
   then do: /* create it */
      run generate-graph-ui .
   end.
   run generate-graph-query
      (input p-browse-id,
       input p-sort-by,
       input p-filter).
   run activate-query
      (input tt-browse-mstr.tt-graph-qry-name,
       output tt-qg-hdl).
   run activate-ui
      (input "GRAPH").
   assign p-graph = tt-gr-hdl.
   run set-query-handle in p-graph
      (input tt-qg-hdl).
END PROCEDURE.
PROCEDURE pair-file-and-field :
/*------------------------------------------------------------------------------
  Purpose:     To match fields with their corresponding database tables.
  Parameters:  input table-list[1..4] - database table name
               input field-list - list of fields to match with table name
               output table-match[1..4] - list of tables matched to fields
  Notes:       The input and output use blanks as a seperator.
------------------------------------------------------------------------------*/
   define input  parameter formula-filter     as character no-undo.
   define input  parameter number-of-tables   as integer   no-undo.
   define input  parameter table-list-1       as character no-undo.
   define input  parameter table-list-2       as character no-undo.
   define input  parameter table-list-3       as character no-undo.
   define input  parameter table-list-4       as character no-undo.
   define input  parameter field-list         as character no-undo.
   define output parameter table-field-list-1 as character no-undo.
   define output parameter table-field-list-2 as character no-undo.
   define output parameter table-field-list-3 as character no-undo.
   define output parameter table-field-list-4 as character no-undo.
   define output parameter table-field-list-5 as character no-undo.
   define variable temp-table-list  as character extent 4 no-undo.
   define variable counter          as integer            no-undo.
   define variable table-count      as integer            no-undo.
   define variable field-count      as integer            no-undo.
   define variable temp-table-name  as character          no-undo.
   assign
      temp-table-list[1] = table-list-1
      temp-table-list[2] = table-list-2
      temp-table-list[3] = table-list-3
      temp-table-list[4] = table-list-4.
   do table-count = 1 to number-of-tables:
      /* Concat an end of string delimiter*/
      assign
         temp-table-name = trim(temp-table-list[table-count]) + "_"
         counter = 1.
      do field-count = 1 to num-entries(field-list," "):
         repeat:
            if substring(temp-table-name,counter,1) = "_" or
               substring(temp-table-name,counter,1) = "." or
               substring(temp-table-name,counter,1) = "-" or
               substring(temp-table-name,counter,1) = " "
            then
               leave.
            assign counter = counter + 1.
         end.
         /* If field list and table list match then add to pair list*/
         if substring(entry(field-count,field-list," "),1,counter) =
            substring(temp-table-name,1,counter)
         then
            case table-count:
               when 1 then
                  if formula-filter = "FORMULA" then
                     assign
                        table-field-list-1 = trim(table-field-list-1) +
                         " " + entry(field-count,field-list," ").
                  else
                     assign table-field-list-1 = field-list.
               when 2 then
                  if formula-filter = "FORMULA" then
                     assign
                        table-field-list-2 = trim(table-field-list-2) +
                         " " + entry(field-count,field-list," ").
                  else
                     assign table-field-list-2 = field-list.
               when 3 then
                  if formula-filter = "FORMULA" then
                     assign
                        table-field-list-3 = trim(table-field-list-3) +
                         " " + entry(field-count,field-list," ").
                  else
                     assign table-field-list-3 = field-list.
               when 4 then
                  if formula-filter = "FORMULA" then
                     assign
                        table-field-list-4 = trim(table-field-list-4) +
                         " " + entry(field-count,field-list," ").
                  else
                     assign table-field-list-4 = field-list.
               when 5 then
                  if formula-filter = "FORMULA" then
                     assign
                        table-field-list-5 = trim(table-field-list-5) +
                          " " + entry(field-count,field-list," ").
               otherwise do:
                  if formula-filter = "FILTER" then
                     assign
                        table-field-list-5 = field-list.
               end.
            end case. /*table-count*/
      end.
   end.
END PROCEDURE.
PROCEDURE find-fields :
/*------------------------------------------------------------------------------
  Purpose:   To retrieve field names from a mathematical formula.
  Parameters:
      input  Formula - mathematical formula.
      output Field-list - list of field names.
  Notes:   - Allows for math functions defined in PROGRESS.
           - Allow field names to have numbers in them.
------------------------------------------------------------------------------*/
   define input  parameter formula    as character no-undo.
   define output parameter field-list as character no-undo.
   define variable counter       as integer init 1 no-undo.
   define variable counter2      as integer        no-undo.
   define variable counter3      as integer        no-undo.
   define variable formula-piece as character      no-undo.
   define variable new-formula   as character      no-undo.
   define variable field-found   as logical        no-undo.
   /* Concatanate an end-of-line delimiter*/
   /* Formula = formula + ".".*/
   if num-entries(formula," ") > 0 then do:
      do counter2 = 1 to num-entries(formula," "):
         assign
            formula-piece = entry(counter2,formula," ") + "|"
            counter = 1
            field-found = no.
         repeat:
            if substring(formula-piece,counter,1) = "_" then do:
               /* Allow for QAD reserved fields, i.e. ar__qad01,*/
               /* src_index1, src_user1, etc.*/
               assign
                  counter = 1.
               repeat:
                  if substring(formula-piece,counter,1) = "*"  or
                     substring(formula-piece,counter,1) = "-"  or
                     substring(formula-piece,counter,1) = "+"  or
                     substring(formula-piece,counter,1) = "/"  or
                     substring(formula-piece,counter,1) = ")"  or
                     substring(formula-piece,counter,1) = "("  or
                     substring(formula-piece,counter,1) = ","  or
                     substring(formula-piece,counter,1) = "="  or
                     substring(formula-piece,counter,1) = "<"  or
                     substring(formula-piece,counter,1) = ">"  or
                     substring(formula-piece,counter,1) = "."  or
                     substring(formula-piece,counter,1) = "~""
                  then do:
                     overlay(formula-piece,counter,1) = " ".
                  end. /*if*/
                  else if substring(formula-piece,counter,1) = "|"
                  then do:
                     assign
                        field-found = yes
                        overlay(formula-piece,counter,1) = " "
                        new-formula = new-formula + " " + formula-piece.
                        leave.
                  end. /*else if*/
                  assign counter = counter + 1.
               end. /*REPEAT*/
               leave.
            end. /*if*/
            if substring(formula-piece,counter,1) = "|" or
               field-found = yes
            then do:
               /* If end-of-line delimiter then remove it and leave loop*/
               leave.
            end. /*if*/
            assign counter = counter + 1.
         end. /*REPEAT*/
         assign counter = 1.
         if field-found = no then do:
            repeat: /* remove any number constants or any symbols*/
               if substring(formula-piece,counter,1) = "*"  or
                  substring(formula-piece,counter,1) = "-"  or
                  substring(formula-piece,counter,1) = "+"  or
                  substring(formula-piece,counter,1) = "/"  or
                  substring(formula-piece,counter,1) = ")"  or
                  substring(formula-piece,counter,1) = "("  or
                  substring(formula-piece,counter,1) = ","  or
                  substring(formula-piece,counter,1) = "."  or
                  substring(formula-piece,counter,1) = "="  or
                  substring(formula-piece,counter,1) = "<"  or
                  substring(formula-piece,counter,1) = ">"  or
                  substring(formula-piece,counter,1) = "~"" or
                  substring(formula-piece,counter,1) = "1"  or
                  substring(formula-piece,counter,1) = "2"  or
                  substring(formula-piece,counter,1) = "3"  or
                  substring(formula-piece,counter,1) = "4"  or
                  substring(formula-piece,counter,1) = "5"  or
                  substring(formula-piece,counter,1) = "6"  or
                  substring(formula-piece,counter,1) = "7"  or
                  substring(formula-piece,counter,1) = "8"  or
                  substring(formula-piece,counter,1) = "9"  or
                  substring(formula-piece,counter,1) = "0"
               then
                  overlay(formula-piece,counter,1) = " ".
               else if substring(formula-piece,counter,1) = "|"
               then do:
                  /* If end-of-line delimiter then remove it and leave loop*/
                  assign
                     overlay(formula-piece,counter,1) = " "
                     new-formula = new-formula + " " + formula-piece.
                  leave.
               end.
               assign counter = counter + 1.
            end. /*REPEAT*/
         end. /*if field-found = no*/
      end. /*DO*/
   end. /*if*/
   assign formula = trim(new-formula).
   /* Build field list and remove any keywords*/
   do counter = 1 to num-entries(formula," "):
      if trim(entry(counter,formula," ")) <> " " and
        keyword-all(trim(entry(counter,formula," "))) = ?
      then do:
         assign field-list = field-list + " " + entry(counter,formula," ").
      end.
   end.
END PROCEDURE.
PROCEDURE construct-printer :
/*------------------------------------------------------------------------------
  Purpose:     To start up a browse printer task.
  Parameters:  input p-browse-id: character: name of browse create
               input p-sort-by  : integer;   column to sort query by
               input p-sort-dir : integer;   direction of sort 1 = ascending, 2 = desc.
  Notes:       It will generate a query if it has to, but first, it will see if
               a browse is already using a query and will use that one
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character no-undo.
   define output parameter p-printer   as handle    no-undo.
   run establish-context
      (input p-browse-id).
   run look-for-code
      (input "PRINTER",
       output l-localrcode-found,
       output l-localpcode-found).
   if not l-localrcode-found and
      not l-localpcode-found
   then do: /* create it */
      run generate-pr .
   end.
   run activate-ui
      (input "PRINTER").
   assign
      p-printer = tt-browse-mstr.tt-pr-hdl.
END PROCEDURE.
PROCEDURE create-browse :
/*------------------------------------------------------------------------------
  Purpose:     Creates the ui piece for the given power browse
  Parameters:  output p-brw-hdl  : handle: handle to ui procedure.
  Notes:
------------------------------------------------------------------------------*/
   run activate-ui
      (input "POWER").
END PROCEDURE.
PROCEDURE create-browse-ui :
/*------------------------------------------------------------------------------
  Purpose:     Creates the source file only for the ui piece of the given browse
  Parameters:  input p-browse-id  : character: name of browse
               input p-eco-number : character: eco number of this generation
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id  as character no-undo.
   define input parameter p-eco-number as character no-undo.
   run establish-context
      (input p-browse-id).
   run generate-ui
      (input p-browse-id,
       input p-eco-number,
       input "BR").
END PROCEDURE.
PROCEDURE create-filename :
/*------------------------------------------------------------------------------
  Purpose:     To generate a filename, based on the input parameter
  Parameters:  input p-stem: stem of filename
               output p-name: complete filename
  Notes:       Adds filename to local temp table so we can remove all
               generated files at program exit.
------------------------------------------------------------------------------*/
   define input parameter p-stem  as character no-undo.
   define output parameter p-name as character no-undo.
   define variable c-rcode        as character no-undo.
   if p-stem = "br" or
      p-stem = "lu" or
      p-stem = "pr" or
      p-stem = "gr"
   then do:
      p-name = substring(tt-browse-mstr.tt-browse, 1, 2, "RAW")
               + p-stem
               + substring(tt-browse-mstr.tt-browse, 3, 4, "RAW")
               + ".p".
   end.
   else do:
      assign
         p-name = substring(p-stem, 1, 2, "RAW")
                  + substring(string(etime, "999999999"), 4, 6, "RAW")
                  + ".p".
   end.
   assign
      c-rcode = entry(1, p-name, ".") + ".r".
   for first tt-file where tt-filename = p-name : end.
   if not available(tt-file) then do:
      create tt-file.
      assign
         tt-file.tt-browse   = tt-browse-mstr.tt-browse
         tt-filename = p-name
         tt-rcode    = c-rcode.
   end.
END PROCEDURE.
PROCEDURE create-lookup-ui :
/*------------------------------------------------------------------------------
  Purpose:     Creates the source file only for the ui piece of the given lookup
  Parameters:  input p-browse-id  : character: name of browse
               input p-eco-number : character: eco number of this generation
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id  as character no-undo.
   define input parameter p-eco-number as character no-undo.
   run establish-context
      (input p-browse-id).
   run generate-ui
      (input p-browse-id,
       input p-eco-number,
       input "LU").
END PROCEDURE.
PROCEDURE establish-context :
/*------------------------------------------------------------------------------
  Purpose:     To define the context so that all procedures refer to the same
               master browse.
  Parameters:  p-browse-id : character, name of the browse to establish context
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   define variable c-br-ui-name as character no-undo.
   define variable c-lu-ui-name as character no-undo.
   define variable c-pr-ui-name as character no-undo.
   define variable c-gr-ui-name as character no-undo.
   for first tt-browse-mstr where tt-browse = p-browse-id : end.
   if not available(tt-browse-mstr) then do:
      do transaction:
         create tt-browse-mstr.
         assign
            tt-browse = p-browse-id.
      end.
      run create-filename
         (input "br",
          output c-br-ui-name).
      run create-filename
         (input "lu",
          output c-lu-ui-name).
      run create-filename
         (input "pr",
          output c-pr-ui-name).
      run create-filename
         (input "gr",
          output c-gr-ui-name).
      assign
         tt-browse-mstr.tt-br-ui-name = c-br-ui-name
         tt-browse-mstr.tt-lu-ui-name = c-lu-ui-name
         tt-browse-mstr.tt-pr-ui-name = c-pr-ui-name
         tt-browse-mstr.tt-gr-ui-name = c-gr-ui-name.
      for first tt-browse-mstr where tt-browse = p-browse-id: end.
      run generate-data.
   end.
END PROCEDURE.
PROCEDURE generate-browse-ui :
/*------------------------------------------------------------------------------
  Purpose:     This procedure establishes new context and generates applicable
               UI files.
  Parameters:  p-browse-id : character, name of the browse context
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   /* Remove context if it already exists*/
     run remove-context
      (input p-browse-id).
   /*Establish new context since it may reflect a new definition*/
   run establish-context
      (input p-browse-id).
   /*Generate the Power Browse UI*/
   if tt-browse-mstr.tt-power then
      run create-browse-ui
         (input p-browse-id,
          input "").
   /* Generate the Look-up Browse UI*/
   if tt-browse-mstr.tt-lookup then
      run create-lookup-ui
         (input p-browse-id,
          input "").
END PROCEDURE.
PROCEDURE generate-data :
/*------------------------------------------------------------------------------
  Purpose:     To create the static data necessary to create the query and the
               UI for the given browse.
  Parameters:  
  Notes:       This routine builds up all the static data necessary to spit out
               the preprocessor definitions used in the browse-UI and query
               templates.
------------------------------------------------------------------------------*/
   /* Create filename (*br*.p*)*/
   assign
       tt-browse-mstr.tt-brpgm-name = substring(tt-browse-mstr.tt-browse,1,2)
                                      + "br" +
                                      substring(tt-browse-mstr.tt-browse,3,4)
                                      + ".p" .
   run generate-table-data.
   run generate-field-data.
END PROCEDURE.
PROCEDURE generate-field-data :
/*------------------------------------------------------------------------------
  Purpose:     To create the static field data necessary to create the query and the
               UI for the given browse.
  Parameters:  
  Notes:       This routine builds up the field data necessary to spit out
               the preprocessor definitions used in the browse-UI and query
               templates.
------------------------------------------------------------------------------*/
   define variable err          as logical       no-undo.
   define variable c-datatype   as character     no-undo.
   define variable c-label      as character     no-undo.
   define variable c-format     as character     no-undo.
   define variable i            as integer       no-undo.
   define variable c-col-label  as character     no-undo.
   define variable c-expression as character     no-undo.
   {gpfilev.i}
   /* For translation purposes, we need to isolate the format of the      */
   /* standard logical of MFG/PRO for use in comparison with the specific */
   /* logicals being placed in a browse. Logicals will be defined "like"  */
   /* mfc_logical except where the format is different. To capture the    */
   /* format of mfc_logical, a dummy frame is created (since formats are  */
   /* a display only mechanism). This frame is never displayed.           */
   define variable l-mfc-logical as logical no-undo.
   define frame f-temp
      l-mfc-logical.
   for first brw_mstr
   fields(brw_desc brw_filter brw_lu_brw brw_name brw_pwr_brw
          brw_view brw_sort_col brw_col_rtn)
   where brw_name = tt-browse-mstr.tt-browse no-lock : end.
   if available(brw_mstr) then do:
      assign
         tt-browse-mstr.tt-description   = c-brw-desc
         tt-browse-mstr.tt-power         = brw_mstr.brw_pwr_brw
         tt-browse-mstr.tt-lookup        = brw_mstr.brw_lu_brw
         tt-browse-mstr.tt-lu-sort-cols  = brw_mstr.brw_sort_col.
      assign
         tt-browse-mstr.tt-drag-back-col = integer(brw_mstr.brw_col_rtn) no-error.
      run cleanup-expression
         (input brw_mstr.brw_filter,
          output tt-filter).
      for each brwf_det
      fields(brwf_datatype brwf_expression brwf_field brwf_format
             brwf_label brwf_seq brwf_table brw_name brwf__qadc01)
      where brwf_det.brw_name = brw_mstr.brw_name
      no-lock:
         assign
            c-datatype   = brwf_datatype
            c-format     = c-brwf-format
            c-label      = c-brwf-label.
         run cleanup-expression
            (input brwf_expression,
             output c-expression).
         for first vue_mstr
         fields(vue_name)
         where vue_name = brw_view
         no-lock : end.
         /* Look for the view field definition */
         if available(vue_mstr) then do:
            if c-datatype = "" or
               c-format   = "" or
               c-label    = "" or
               (c-expression = "" and brwf_table = "")
            then do:
               for first vuf_det
               fields(vue_name vuf_datatype vuf_expression vuf_field
                      vuf_format vuf_label vuf_table)
                  where vuf_det.vue_name  = vue_mstr.vue_name
                  and   vuf_det.vuf_table = brwf_det.brwf_table
                  and   vuf_det.vuf_field = brwf_det.brwf_field
               no-lock : end.
               if c-datatype = "" then
                  assign
                     c-datatype = if available(vuf_det)
                                  then vuf_datatype
                                  else "".
               if c-format = "" then
                  assign
                     c-format   = if available(vuf_det)
                                  then c-vuf-format
                                  else "".
               if c-label = "" then
                  assign
                     c-label    = if available(vuf_det)
                                  then c-vuf-label
                                  else "".
               if c-expression = "" and brwf_table = ""
               then do:
                  if available(vuf_det) then do:
                     if vuf_expression <> "" then do:
                        run cleanup-expression
                           (input vuf_expression,
                            output c-expression).
                     end.
                  end.
               end.
            end.  /* look view in field definition */
         end. /* available vue_mstr */
         if c-label = "" then do: /* check lbld_det */
            for first lbld_det where lbld_fieldname = brwf_field
                and   lbld_execname = ""
            no-lock:
               c-label = getTermLabel(lbld_term, 45).
            end.
         end.
         /* Do we have to look at the metaschema? */
         if c-datatype = "" or
            c-format = ""   or
            c-label = ""
         then do:
            for first _file no-lock
                where _file-name = brwf_table:
            end.
            if available _file then do:
               for first _field of _file where
                  _field-name =
                     if index(brwf_field,"[") = 0
                     then
                        brwf_field
                     else
                        substring(brwf_field,1,index(brwf_field,"[") - 1)
               no-lock:
                  if c-datatype = "" then
                     c-datatype = _data-type.
                  if c-label = "" and _col-label <> ? then
                     c-col-label = _col-label.
                  if c-format = "" and
                     (c-datatype <> "logical" or
                     (c-datatype  = "logical" and
                        _format <> l-mfc-logical:format in frame f-temp))
                  then
                     c-format = _format.
                  if c-label = "" then
                     c-label = _label +
                               if index(brwf_field,"[") = 0 then ""
                               else
                                  substring(brwf_field,index(brwf_field,"[")).
               end. /* for first _field */
            end. /* available _file */
            else do:
               {gpfilpre.i &file_name=brwf_table}
               if file_found then do:
                  {gprun.i ""gpbrwdat.p""
                     "(input brwf_table,
                       input brwf_field,
                       input-output c-datatype,
                       input-output c-label,
                       input-output c-col-label,
                       input-output c-format)"}
               end.
               {gpfilpst.i}
            end. /* if not available _file */
         end. /* we have to go to the metaschema */
         create tt-browse-field.
         assign
            tt-browse-field.tt-browse = tt-browse-mstr.tt-browse
            tt-seq         = brwf_seq
            tt-table-name  = brwf_table
            tt-field-name  = if brwf_table <> "" then brwf_field
                             else "local-" + string(brwf_seq)
            tt-datatype    = c-datatype
            tt-format      = c-format
            tt-label       = c-label
            tt-col-label   = c-col-label
            tt-expression  = c-expression
            tt-num-fields = tt-num-fields + 1.
      end. /* for each brwf_det ... */
   end.
END PROCEDURE.
PROCEDURE generate-filtered-query :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  p-browse-id: character: name of browse for which we build query
               p-fil-frs:   character: delimited list of "from" values
               p-fil-tos:   character: delimited list of "to" values
               p-sort-by:   integer
               p-descending:logical
  Notes:       This is where we use the "from" and "to" fields to construct
               a source code file which will then be compiled and run as
               a persistent procedure.
               It assumes that the correct data are already in the filter
               variables.
------------------------------------------------------------------------------*/
   define input parameter p-browse-id  as character no-undo.
   define input parameter p-fil-frs    as character no-undo.
   define input parameter p-fil-tos    as character no-undo.
   define input parameter p-sort-by    as integer   no-undo.
   define input parameter p-descending as logical   no-undo.
   define output parameter p-query     as handle    no-undo.
   run establish-context
      (input p-browse-id).
   if valid-handle(tt-browse-mstr.tt-qf-hdl) then do:
      run close-query in tt-qf-hdl.
      delete procedure tt-qf-hdl.
      assign tt-qf-hdl = ?.
   end.
   assign
      c-fil-frs = p-fil-frs
      c-fil-tos = p-fil-tos.
   run create-filename
      (input "qf",
       output tt-browse-mstr.tt-filter-qry-name).
   run generate-query
      (input "QUERY",
       input "FILT",
       input tt-browse-mstr.tt-filter-qry-name,
       input p-sort-by,
       input p-descending,
       input "",
       input "").
   run activate-query
      (input tt-browse-mstr.tt-filter-qry-name,
       output tt-qf-hdl).
   p-query = tt-qf-hdl.
END PROCEDURE.
PROCEDURE generate-graph-ui :
/*------------------------------------------------------------------------------
  Purpose:     Takes the static data and writes out a source code file
               to handle graph requests.
  Parameters:  
  Notes:       This routine writes out the preprocessors for the browse graph
------------------------------------------------------------------------------*/
   run generate-ui
      (input tt-browse-mstr.tt-browse,
       input "",
       input "GR").
END PROCEDURE.
PROCEDURE generate-graph-query :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  p-browse-id: character: name of browse for which we build query
               p-sort-by:   integer
               p-filter :   integer  1 = Unfiltered, 2 = Filtered
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id  as character no-undo.
   define input parameter p-sort-by    as integer   no-undo.
   define input parameter p-filter     as integer   no-undo.
   define variable c-filter-type as character no-undo.
   assign
      c-filter-type = (if p-filter = 1 then "UNFILT" else "FILT").
   run establish-context
      (input p-browse-id).
   if valid-handle(tt-browse-mstr.tt-qg-hdl) then do:
      run close-query in tt-qg-hdl.
      delete procedure tt-qg-hdl.
      tt-ql-hdl = ?.
      run remove-file
         (input tt-graph-qry-name).
   end.
   run create-filename
      (input "qg",
       output tt-browse-mstr.tt-graph-qry-name).
   run generate-query
      (input "QUERY",
       input c-filter-type,
       input tt-browse-mstr.tt-graph-qry-name,
       input p-sort-by,
       input no,
       input "",
       input "").
END PROCEDURE.
PROCEDURE add_another_where_clause :
/*------------------------------------------------------------------------------
  Purpose:     Output another "where" clause
  Parameters:  join-phrase: join logic of where statement.
               where-clause: yes/no. if where clause is being used.
               filter-expression: any filter logic in where statement.
               prime-expression: if no join or filter then use prime expression.
               logical-db-expression: logical database name.
               table-expression: table name.
  Notes:
------------------------------------------------------------------------------*/
   define input parameter join-phase            as character no-undo.
   define input parameter join-type             as character no-undo.
   define input parameter where-clause          as logical   no-undo.
   define input parameter user-defined-logic    as character no-undo.
   define input parameter filter-logic          as character no-undo.
   define input parameter prime-expression      as character no-undo.
   define input parameter logical-db-expression as character no-undo.
   define input parameter table-expression      as character no-undo.
   if join-phase <> "" then do:
      if user-defined-logic <> "" then do:
         if filter-logic <> "" then do:
            put unformatted " NO-LOCK,~~" skip "EACH "
                            logical-db-expression + "." +
                            table-expression " "
                            "WHERE (" + join-phase + ")" +
                            " AND (" + user-defined-logic + ")" +
                            " AND (" + filter-logic + ") " + join-type.
         end.
         else do:
              put unformatted " NO-LOCK,~~" skip "EACH "
                              logical-db-expression + "." +
                              table-expression " "
                              "WHERE (" + join-phase + ")" +
                              " AND (" + user-defined-logic ") " + join-type.
         end.
      end.
      else do:
         if filter-logic <> "" then do:
            put unformatted " NO-LOCK,~~" skip "EACH "
                            logical-db-expression + "." +
                            table-expression " "
                            "WHERE (" + join-phase + ")" +
                            " AND (" + filter-logic + ") " + join-type.
         end.
         else do:
              put unformatted " NO-LOCK,~~" skip "EACH "
                              logical-db-expression + "." +
                              table-expression " "
                              "WHERE " + join-phase + " " + join-type.
         end.
      end.
   end.
   else do:
      if user-defined-logic <> "" then do:
         if filter-logic <> "" then do:
            put unformatted " NO-LOCK,~~" skip "EACH "
                            logical-db-expression + "." +
                            table-expression " "
                            "WHERE (" + user-defined-logic + ")" +
                            " AND (" + filter-logic + ") " + join-type.
         end.
         else do:
              put unformatted " NO-LOCK,~~" skip "EACH "
                              logical-db-expression + "." +
                              table-expression " "
                              "WHERE " + user-defined-logic + " " + join-type.
         end.
      end.
      else do:
         if filter-logic <> "" then do:
            put unformatted " NO-LOCK,~~" skip "EACH "
                            logical-db-expression + "." +
                            table-expression " "
                            "WHERE " + filter-logic + " " + join-type.
         end.
         else do:
              if prime-expression  <> "" and
                 not where-clause then do:
         /* THE BELOW CODED WHERE-CLAUSE IS USED AS INDEX-HINT FOR  */
         /* ORACLE DB BUT EXCLUDED FOR PROGRESS DB FOR PERFORMANCE. */
         /* THE BELOW CODE ALSO ADDS (EACH ) STATEMENT  */
         /* FOR A TABLE WHICH HAS NO WHERE-CLAUSE ASSOCIATED TO IT. */
         /* THIS WILL SUPRESS THE ERROR OF INVALID BROWSE DEFINITION*/
                 if dbtype(logical-db-expression) = "ORACLE" then
                    put unformatted " NO-LOCK,~~" skip "EACH "
                                    logical-db-expression + "." +
                                    table-expression " "
                                    "WHERE " + prime-expression +
                                    " " + join-type.
                 else
                    put unformatted " NO-LOCK,~~" skip "EACH "
                                    logical-db-expression + "." +
                                    table-expression " " + join-type.
              end.
              /* FOR POWER BROWSE HAVING TWO OR MORE TABLE WITH-  */
              /* OUT A JOIN, THE BELOW  CODE ADDS (EACH ) STATEMENT IF THE VALUE IN VARIABLE WHERE- */
              /* CLAUSE IS SET TO YES                             */
              else
                 put unformatted " NO-LOCK,~~" skip "EACH "
                                 logical-db-expression + "." +
                                 table-expression " " + join-type.
         end.
      end.
   end.
END PROCEDURE.
PROCEDURE generate-pr :
/*------------------------------------------------------------------------------
  Purpose:     Takes the static data and writes out a source code file
               to handle print requests.
  Parameters:  
  Notes:       This routine writes out the preprocessors for the browse printer
------------------------------------------------------------------------------*/
   run generate-ui
      (input tt-browse-mstr.tt-browse,
       input "",
       input "PR").
END PROCEDURE.
PROCEDURE generate-query :
/*------------------------------------------------------------------------------
  Purpose:     To create a dynamic query at runtime for both browses and lookups
  Parameters:  browse-type: character: "QUERY" or "LOOKUPQUERY"
               p-qry-type: character: "FILT" or "UNFILT"
               p-qry-name: character: name of file to write to
               p-sort-by:  integer:   field (column) to sort by
               p-descending: logical: yes = descending
               p-filename: character: name of file to output to
               p-start:    character: place to open query at
  Notes:       This routine writes out the preprocessor variables for the
               designated query.
------------------------------------------------------------------------------*/
   define input parameter browse-type  as character no-undo. /*BROWSE*/
   define input parameter p-qry-type   as character no-undo. /*BROWSE*/
   define input parameter p-qry-name   as character no-undo. /*BROWSE*/
   define input parameter p-sort-by    as integer   no-undo. /*BROWSE/LOOKUP*/
   define input parameter p-descending as logical   no-undo. /*BROWSE*/
   define input parameter p-filename   as character no-undo. /*LOOKUP*/
   define input parameter p-start      as character no-undo. /*LOOKUP*/
   define variable c-scop             as character
      initial "~&SCOPED-DEFINE " no-undo.
   define variable i                  as integer            no-undo.
   define variable c-flt-expr         as character extent 5 no-undo.
   define variable c-field-list       as character extent 5 no-undo.
   define variable c-temp             as character          no-undo.
   define variable l-use-field-list   as logical            no-undo.
   define variable where-clause       as logical init no    no-undo.
   define variable formula-field-list as character          no-undo.
   define variable table-field-list   as character extent 5 no-undo.
   define variable counter            as integer            no-undo.
   define variable temp-field-list    as character          no-undo.
   run verify-ldbs.
   if browse-type = "LOOKUPQUERY" then do:
      output to value(p-filename).
      run write-file-header
         (input p-filename,
          input browse-type,
          input "").
   end.
   else if browse-type = "QUERY" then do:
      output to value(p-qry-name).
      run write-file-header
         (input p-qry-name,
          input browse-type,
          input "").
   end.
   /*BROWSE DESCRIPTION*/
   put unformatted
      "&GLOB BR-BROWSE-DESCRIPTION " tt-browse-mstr.tt-description
      skip(1).
   /* Get field lists for each table in query*/
   do i = 1 to tt-num-tables:
      run get-query-field-list
         (input tt-browse-mstr.tt-browse,
          input tt-browse-mstr.tt-table[i],
          output c-temp).
      assign c-field-list[i] = c-temp.
   end.
   run can-use-field-list
      (input tt-browse-mstr.tt-browse,
       output l-use-field-list).
   if not l-use-field-list then do:
      for each  tt-browse-field
          where tt-browse-field.tt-browse = tt-browse-mstr.tt-browse
          and   tt-browse-field.tt-table-name = ""
      no-lock:
         run find-fields
            (input tt-expression,
             output formula-field-list).
         run pair-file-and-field
            (input  "FORMULA",
             input  tt-num-tables,
             input  tt-browse-mstr.tt-table[1],
             input  tt-browse-mstr.tt-table[2],
             input  tt-browse-mstr.tt-table[3],
             input  tt-browse-mstr.tt-table[4],
             input  formula-field-list,
             output table-field-list[1],
             output table-field-list[2],
             output table-field-list[3],
             output table-field-list[4],
             output table-field-list[5]).
         do i = 1 to tt-num-tables:
            if table-field-list[i] <> "" then
            do counter = 1 to 5:
               /* Remove duplicates in the lists*/
               if table-field-list[counter] = c-field-list[counter]
               then
                  table-field-list[counter] = "".
            end.
            /* Join the two lists*/
            assign
               c-field-list[i] = replace(c-field-list[i], ")", " " +
                                 trim(table-field-list[i])) + ")"
               l-use-field-list = yes.
         end. /*do i = 1 to tt-num-tables*/
      end. /*for each tt-browse-field where*/
   end. /*if not l-use-field-list*/
   /* Fully qualify table names in the query. This qualification is   */
   /* necessary for Multi-DB environments so that ambigious references*/
   /* to table names do not occur during runtime query generation.    */
   /* TABLE & FIELD LIST SECTION*/
   put unformatted
      c-scop "Q-FIRST-TABLE " tt-l-db[1] + "." + tt-browse-mstr.tt-table[1]
      skip
      c-scop "Q-FIRST-FIELD-LIST " (if l-use-field-list then "FIELDS " +
                                       c-field-list[1] else " ")
      skip.
   if tt-num-tables > 1 then do:
      put unformatted
         c-scop "Q-2ND-TABLE " tt-l-db[2] + "." + tt-browse-mstr.tt-table[2]
         skip
         c-scop "Q-2ND-FIELD-LIST " (if l-use-field-list then "FIELDS " +
                                     c-field-list[2] else " ")
         skip.
   end.
   if tt-num-tables > 2 then do:
      put unformatted
         c-scop "Q-3RD-TABLE " tt-l-db[3] + "." + tt-browse-mstr.tt-table[3]
         skip
         c-scop "Q-3RD-FIELD-LIST " (if l-use-field-list then "FIELDS " +
                                     c-field-list[3] else " ")
         skip.
   end.
   if tt-num-tables > 3 then do:
      put unformatted
         c-scop "Q-4TH-TABLE " tt-l-db[4] + "." + tt-browse-mstr.tt-table[4]
         skip
         c-scop "Q-4TH-FIELD-LIST " (if l-use-field-list then "FIELDS " +
                                     c-field-list[4] else " ")
         skip.
   end.
   put unformatted
      /* Number of tables */
      c-scop "Q-NUM-TABLES " tt-num-tables skip(1)
      /* Parameters */
      c-scop "cparm1 " "initial " "~""  tt-cparm1 "~"" skip
      c-scop "cparm2 " "initial " "~""  tt-cparm2 "~"" skip
      c-scop "cparm3 " "initial " "~""  tt-cparm3 "~"" skip
      c-scop "cparm4 " "initial " "~""  tt-cparm4 "~"" skip
      c-scop "cparm5 " "initial " "~""  tt-cparm5 "~"" skip
      c-scop "nparm1 " "initial "       tt-nparm1 skip
      c-scop "nparm2 " "initial "       tt-nparm2 skip
      c-scop "dparm1 " "initial "       tt-dparm1 skip
      c-scop "dparm2 " "initial "       tt-dparm2 skip
      c-scop "lparm1 " "initial "       tt-lparm1 skip
      c-scop "lparm2 " "initial "       tt-lparm2 skip(1).
   for first tt-browse-field
   where tt-browse-field.tt-browse = tt-browse-mstr.tt-browse
   and   tt-seq = p-sort-by no-lock : end.
   if available(tt-browse-field) then do:
      put unformatted
         c-scop "Q-BY-EXPR " if tt-table-name = "" then tt-expression
                             else tt-table-name + "." + tt-field-name
         skip
         c-scop "Q-DESCENDING " if p-descending and browse-type = "QUERY"
                                then "DESCENDING"
                                else ""
         skip.
   end.
   run substitute-globals
      (input-output tt-filter).
   do i = 1 to tt-num-tables:
      if (tt-join[i] <> "")
      then do:
         run substitute-globals(input-output tt-join[i]).
      end. /* IF (tt-join[i] <> "") THEN */
   end. /* DO i = 1 TO tt-num-tables: */

   if tt-num-tables > 1 and tt-filter <> "" then do:
      /* Strip out all data that is not field data*/
      run find-fields
         (input tt-filter,
          output temp-field-list).
      /* If seperatable or only one table in logic then pair filter with table*/
      if temp-field-list <> "" then
         run pair-file-and-field
            (input  "FILTER",
             input  tt-num-tables,
             input  tt-browse-mstr.tt-table[1],
             input  tt-browse-mstr.tt-table[2],
             input  tt-browse-mstr.tt-table[3],
             input  tt-browse-mstr.tt-table[4],
             input  trim(temp-field-list),
             output filter-logic[1],
             output filter-logic[2],
             output filter-logic[3],
             output filter-logic[4],
             output filter-logic[5]).
      /* Put filter data into lowest table*/
      if filter-logic[4] <> "" then do:
         assign
            filter-logic[1] = ""
            filter-logic[2] = ""
            filter-logic[3] = ""
            filter-logic[4] = tt-filter.
      end.
      else if filter-logic[3] <> "" then do:
         assign
            filter-logic[1] = ""
            filter-logic[2] = ""
            filter-logic[3] = tt-filter.
      end.
      else if filter-logic[2] <> "" then do:
         assign
            filter-logic[1] = ""
            filter-logic[2] = tt-filter.
      end.
      else if filter-logic[1] <> "" then
         filter-logic[1] = tt-filter.
      else do: /*default*/
         assign
            filter-logic[1] = ""
            filter-logic[2] = ""
            filter-logic[3] = ""
            filter-logic[4] = ""
            filter-logic[5] = tt-filter.
      end.
      assign tt-filter = "".
   end. /*if tt-num-tables > 1*/
   else
      /* RESET DEFAULT VALUES FOR SINGLE TABLE */
      assign
         filter-logic[1] = ""
         filter-logic[2] = ""
         filter-logic[3] = ""
         filter-logic[4] = ""
         filter-logic[5] = "".
   /* Number of filter values / for each statement */
   put unformatted skip
      c-scop "Q-NUM-FILT-VALS " tt-num-fields
      skip(1)
      c-scop "Q-FOR-EACH FOR " "EACH "  tt-browse-mstr.tt-l-db[1] + "." +
              tt-browse-mstr.tt-table[1] " ".
   if browse-type = "LOOKUPQUERY" then do:
      /* This constructs the filter expression in ALL lookups*/
      for first tt-browse-field of tt-browse-mstr
      where (tt-seq = p-sort-by) : end.
      if available(tt-browse-field) then do:
         do i = 1 to tt-num-tables:
            if tt-table-name = tt-browse-mstr.tt-table[i] then do:
               run build-sub-expression
                  (input p-start,
                   input if tt-table-name = "" then tt-expression
                         else (tt-table-name + "." + tt-field-name),
                   input tt-datatype,
                   input "FROM",
                   input-output c-flt-expr[i]).
            end.
            else do:
               c-flt-expr[i] = "".
            end. /*else*/
         end. /*do i = 1 to tt-num-tables*/
         /* THE BELOW CODE UPDATES VARIABLE C-FLT-EXPR[5] WITH*/
         /* LOCAL VARIABLE FILTER EXPRESSION FOR LOOKUPS      */
         if tt-table-name = "" then do:
            run build-sub-expression
               (input p-start,
                input tt-expression,
                input tt-datatype,
                input "FROM",
                input-output c-flt-expr[5]).
         end. /*IF TT-TABLE-NAME = ""*/
         else
            c-flt-expr[5] = "".
      end.
   end. /*if browse-type = "LOOKUPQUERY"*/
   else do: /*browse-type = "QUERY"*/
      if p-qry-type = "FILT" then do:
         do i = 1 to tt-num-tables:
            /* Get filters by table*/
            run build-filter-expression
               (input tt-browse-mstr.tt-table[i],
                output c-temp).
            c-flt-expr[i] = c-temp.
         end.
         /* Get filters on local variable expressions*/
         run build-filter-expression
            (input "",
             output c-temp).
         c-flt-expr[5] = c-temp.
      end.
   end.
   if tt-filter <> "" or
      c-flt-expr[5] <> ""
   then do:
      if tt-join[1] = "" or
         tt-join[2] = "" or
         tt-join[3] = "" or
         tt-join[4] = ""
      then
         if tt-num-tables = 1 and
            c-flt-expr[1] <> "" then.
         else if tt-num-tables = 1 and
            filter-logic[1] <> "" then.
         else
            where-clause = yes.
   end.
   /* 1st Conditional False/False/False */
   if tt-join[1]      <> "" and
      filter-logic[1] <> "" and
      c-flt-expr[1]   <> ""
   then
      put unformatted "WHERE " + tt-join[1] + " AND " + c-flt-expr[1] +
                      " AND " + filter-logic[1].
   /* 2nd Conditional False/True/False*/
   else if tt-join[1] <> "" and
      filter-logic[1] =  "" and
      c-flt-expr[1]   <> ""
   then
      put unformatted "WHERE " + tt-join[1] + " AND " + c-flt-expr[1].
   /* 3rd Conditional False/False/True*/
   else if tt-join[1] <> "" and
      filter-logic[1] <> "" and
      c-flt-expr[1]   =  ""
   then
      put unformatted "WHERE " + tt-join[1] + " AND " + filter-logic[1].
   /* 4th Conditional False/True/True*/
   else if tt-join[1] <> "" and
      filter-logic[1] =  "" and
      c-flt-expr[1]   =  ""
   then
      put unformatted "WHERE " + tt-join[1].
   /* 5th Conditional True/False/False*/
   else if tt-join[1] =  "" and
      filter-logic[1] <> "" and
      c-flt-expr[1]   <> ""
   then
      put unformatted "WHERE " + filter-logic[1] + " AND " + c-flt-expr[1].
   /* 6th Conditional True/False/True*/
   else if tt-join[1] =  "" and
      filter-logic[1] <> "" and
      c-flt-expr[1]   =  ""
   then
      put unformatted "WHERE " + filter-logic[1].
   /* 7th Conditional True/True/False*/
   else if tt-join[1] =  "" and
      filter-logic[1] =  "" and
      c-flt-expr[1]   <> ""
   then
      put unformatted "WHERE " + c-flt-expr[1].
   /* 8th Conditional True/True/True*/
   else if tt-prime-expr[1] <> "" and
      dbtype(tt-l-db[1]) = "ORACLE" and
      not where-clause
   then
      /* Put in table.field >= "" so that ORACLE can resolve */
      /* the index and avoid a full table scan               */
      put unformatted "WHERE " + tt-prime-expr[1].
   do counter = 1 to 3:
      if tt-num-tables > counter then do:
         run add_another_where_clause
            (input tt-join[counter + 1],
             input tt-join-type[counter + 1],
             input where-clause,
             input c-flt-expr[counter + 1],
             input filter-logic[counter + 1],
             input tt-prime-expr[counter + 1],
             input tt-l-db[counter + 1],
             input tt-browse-mstr.tt-table[counter + 1]).
      end. /*if tt-num-tables > counter*/
   end. /*do counter = 1 to 3*/
   /* Check to ensure there is filter data */
   if tt-filter <> "" then do:
      /* For filtered queries, add "()" around    */
      /* the filtered expression for conjunctions.*/
      if tt-join[1] <> "" or
         tt-join[2] <> "" or
         tt-join[3] <> "" or
         tt-join[4] <> ""
      then
         put unformatted " AND (" + tt-filter + ")".
      else do:
         if tt-num-tables = 1 and
            c-flt-expr[1] <> ""
         then
            put unformatted " AND (" + tt-filter + ")".
         else
            put unformatted " WHERE " + tt-filter.
      end.
      if c-flt-expr[5] <> "" then do:
         if filter-logic[5] <> "" then do:
            put unformatted
               " AND (" + c-flt-expr[5] + ")" + " AND (" + filter-logic[5] + ")".
         end.
         else do:
            put unformatted
               " AND (" + c-flt-expr[5] + ")".
         end.
      end.
      else do:
         if filter-logic[5] <> "" then do:
            put unformatted
               " AND (" + filter-logic[5] + ")".
         end.
      end.
   end.
   else if filter-logic[5] <> "" then do:
      if tt-join[1] <> "" or
         tt-join[2] <> "" or
         tt-join[3] <> "" or
         tt-join[4] <> ""
      then do:
         if c-flt-expr[5] <> "" then do:
            if filter-logic[5] <> "" then do:
               put unformatted
                  " AND (" + c-flt-expr[5] + ")" +
                  " AND (" + filter-logic[5] + ")".
            end.
            else do:
               put unformatted
                  " AND (" c-flt-expr[5] + ")".
            end.
         end.
      end.
      else do:
         if tt-num-tables = 1 then do:
            if browse-type = "QUERY" then do:
               if c-flt-expr[5] <> "" then do:
                  if filter-logic[5] <> "" then do:
                     put unformatted
                        " AND (" + c-flt-expr[5] ") AND (" + filter-logic[5] ")".
                  end.
                  else do:
                     put unformatted
                        " AND " + c-flt-expr[5].
                  end. /*else*/
               end. /*c-flt-expr[5] <> ""*/
            end. /*if browse-type = "QUERY"*/
            else do:
               if filter-logic[5] <> "" then do:
                  put unformatted
                     " AND (" + filter-logic[5] + ")".
               end. /*if filter-logic[5] <> ""*/
            end. /*else*/
         end. /* if tt-num-tables */
         else do:
            if browse-type = "QUERY" then
               if c-flt-expr[5] <> "" then do:
                  put unformatted
                     " WHERE (" + c-flt-expr[5] + ") AND (" +
                     filter-logic[5] + ")".
               end.
               else do:
                  if c-flt-expr[5] <> "" then do:
                     if filter-logic[5] <> "" then do:
                        put unformatted
                           " WHERE (" + c-flt-expr[5] + ") AND (" +
                             filter-logic[5] + ")".
                     end. /*if filter-logic[5] <> ""*/
                     else do:
                        put unformatted
                           " WHERE " + c-flt-expr[5].
                     end. /*else*/
                  end. /*if c-flt-expr[5] <> ""*/
               end. /*else*/
            else do:
               if tt-filter <> "" then do:
                  if filter-logic[5] <> "" then do:
                     put unformatted
                        " WHERE (" + tt-filter + ") AND (" +
                        filter-logic[5] + ")".
                  end. /*if filter-logic[5] <> ""*/
                  else do:
                     put unformatted
                        " WHERE " + tt-filter.
                  end. /*else*/
               end. /*if tt-filter <> ""*/
            end. /*else*/
         end. /*else*/
      end. /*else*/
   end. /*else*/
   /* THE BELOW CODE GENERATES QUERY WHEN ONLY C-FLT-EXPR[5] */
   /* CONTAINS VALUE. LOCAL VARIABLES FILTER EXPRESSION ARE  */
   /* STORED IN C-FLT-EXPR[5]                                */
   else if c-flt-expr[5] <> "" then do:
      if tt-join[tt-num-tables]      <> "" or
         c-flt-expr[tt-num-tables]   <> "" or
         filter-logic[tt-num-tables] <> ""
      then
         put unformatted " AND (" c-flt-expr[5] + ")".
      else
         put unformatted " WHERE " + c-flt-expr[5].
   end.
   put unformatted
      " NO-LOCK"
      skip(1)
      "~{" "query.i}"
      skip.
   output close.
END PROCEDURE.
PROCEDURE generate-table-data :
/*------------------------------------------------------------------------------
  Purpose:     To create the static table data necessary to create the query and the
               UI for the given browse.
  Parameters:  
  Notes:       This routine builds up the table-specific data
------------------------------------------------------------------------------*/
   define variable c-temp-join as character no-undo.
   for each brwt_det
   fields(brwt_join brwt_table brw_name brwt__qadc01)
   where brw_name = tt-browse-mstr.tt-browse
   no-lock:
      assign
         tt-browse-mstr.tt-num-tables = tt-num-tables + 1
         tt-table[tt-num-tables]      = brwt_table.
      run cleanup-expression
         (input brwt_join,
          output c-temp-join).

      if tt-num-tables > 1 and brwt__qadc01 = "yes" then
         tt-browse-mstr.tt-join-type[tt-num-tables] = "OUTER-JOIN".
      assign
         tt-join[tt-num-tables] = c-temp-join.
      if tt-table[tt-num-tables] <> "" then
         run p-get-prime-where-expr
            (input  tt-table[tt-num-tables],
             output tt-prime-expr[tt-num-tables]).
   end.
END PROCEDURE.
PROCEDURE p-get-prime-where-expr :
/*------------------------------------------------------------------------------
  Purpose:     To derive a "where" expression which uses the prime index
  Parameters:  input p-table (C) - name of the table whose index expression
               we want output p-prime-index (C) - the resulting expression
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-table            as character no-undo.
   define output parameter p-prime-where-expr as character no-undo.
   define variable db-hold      as character no-undo.
   define variable db-point     as integer   no-undo.
   define variable p-field-name as character no-undo.
   define variable p-field-type as character no-undo.
   define variable p-field-min  as character no-undo.
   assign
      p-prime-where-expr = "TRUE"  /* pre-condition return value */
      db-hold = ?.
   /* Get current dictdb assignment and save it*/
   alias-loop:
   do db-point = 1 to num-dbs:
      if dbtype(db-point) = "PROGRESS" then do:
         if ldbname(db-point) = ldbname("dictdb") then do:
            assign db-hold = ldbname(db-point).
            leave alias-loop.
         end.
      end.
   end.
   /* Find the given table in the connected databases*/
   find-loop:
   do db-point = 1 to num-dbs:
      if dbtype(db-point) = "PROGRESS" then do:
         create alias dictdb for database value (ldbname(db-point)).
         {gprun.i ""gpbrpidx.p""
            "(input p-table,
              output p-field-name,
              output p-field-type,
              output p-field-min)"}
         if p-field-name <> "" then do:
            p-prime-where-expr = p-table + "." +
                                 p-field-name + " >= " +
                                 p-field-min.
            leave find-loop.
         end.
      end.
   end. /*do for each database*/
   /* Restore alias to original database*/
   if db-hold <> ? then
      create alias dictdb for database value (db-hold).
END PROCEDURE.
PROCEDURE generate-unfiltered-query :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  p-browse-id: character
               p-sort-by:  integer:   field to sort by
               p-descending: logical: yes = descending
               p-query-hdl:  handle
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id  as character no-undo.
   define input parameter p-sort-by    as integer   no-undo.
   define input parameter p-descending as logical   no-undo.
   define output parameter p-query-hdl as handle    no-undo.
   run establish-context
      (input p-browse-id).
   if valid-handle(tt-browse-mstr.tt-qr-hdl) then do:
      run close-query in tt-qr-hdl.
      delete procedure tt-qr-hdl.
      assign tt-qr-hdl = ?.
   end.
   run create-filename
      (input "qr",
       output tt-browse-mstr.tt-raw-qry-name).
   run generate-query
      (input "QUERY",
       input "UNFILT",
       input tt-browse-mstr.tt-raw-qry-name,
       input p-sort-by,
       input p-descending,
       input "",
       input "").
   run activate-query
      (input tt-browse-mstr.tt-raw-qry-name,
       output tt-qr-hdl).
   assign p-query-hdl = tt-qr-hdl.
END PROCEDURE.
PROCEDURE generate-ui :
/*------------------------------------------------------------------------------
  Purpose:     To generate the UI construction and to localize the invocation
               of gpbuigen.p to a single instance of gprun.
  Parameters:  input  p-browse-id character
               input  p-eco-num   character
               input  p-type      character
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   define input parameter p-eco-num   as character no-undo.
   define input parameter p-type      as character no-undo.
   {gprun.i ""gpbuigen.p""
      "(input p-browse-id,
        input p-eco-num,
        input this-procedure,
        input p-type)"}
END PROCEDURE.
PROCEDURE get-browse-attributes :
/*------------------------------------------------------------------------------
  Purpose:     To get the various attributes defined for the browse
  Parameters:  input  p-browse-id character
               input  p-attribute character
               output p-value     character
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character no-undo.
   define input  parameter p-attribute as character no-undo.
   define output parameter p-value     as character no-undo.
   for first tt-browse-mstr where tt-browse = p-browse-id : end.
   if available(tt-browse-mstr) then do:
      case p-attribute:
         when "DESCRIPTION" then p-value = tt-browse-mstr.tt-description.
         when "DRAG-BACK"   then p-value = string(tt-browse-mstr.tt-drag-back-col).
         when "HI-CHAR"     then p-value = hi_char.
         when "SRCH-MSG"    then p-value = c-srch-msg.
         when "V-FORMAT"    then p-value = c-vuf-format.
         when "V-LABEL"     then p-value = c-vuf-label.
         when "B-FORMAT"    then p-value = c-brwf-format.
         when "B-LABEL"     then p-value = c-brwf-label.
      end case.
   end.
END PROCEDURE.
PROCEDURE get-field-list :
/*------------------------------------------------------------------------------
  Purpose:     To return a delimted list of all fields/expressions to be used
               for drilldowns.
  Parameters:  input p-browse-id: character
               output p-field-list: character
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id  as character no-undo.
   define output parameter p-field-list as character no-undo.
   define variable i as integer no-undo.
   do i = 1 to 20:
      for first tt-browse-field
         where tt-browse = p-browse-id
           and tt-seq = i
      no-lock : end.
      if available tt-browse-field then do:
         {gpappend.i p-field-list
            "(if tt-field-name = '' then tt-expression
              else (if tt-table-name = '' then tt-field-name
                    else tt-table-name + '.' + tt-field-name))"}
      end.
      else do:
         {gpappend.i p-field-list 'null-char'}
      end.
   end.
END PROCEDURE.
PROCEDURE get-new-lookup-query :
/*------------------------------------------------------------------------------
  Purpose:     To get a new query for the specified lookup
  Parameters:  input p-lookup-id: name of lookup
               input p-index: character: column to sort on
               input p-start: character: first record of query
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-lookup-id as character no-undo.
   define input  parameter p-index     as integer   no-undo.
   define input  parameter p-start     as character no-undo.
   define output parameter p-query     as handle    no-undo.
   run establish-context
      (input p-lookup-id).
   if valid-handle(tt-browse-mstr.tt-ql-hdl) then do:
      run close-query in tt-ql-hdl.
      delete procedure tt-ql-hdl.
      assign tt-ql-hdl = ?.
      run remove-file
         (input tt-lookup-qry-name).
   end.
   run create-filename
      (input "ql",
       output tt-browse-mstr.tt-lookup-qry-name).
   run generate-query
      (input "LOOKUPQUERY",
       input "",
       input "",
       input p-index,
       input ?,
       input tt-browse-mstr.tt-lookup-qry-name,
       input p-start).
   run activate-query
      (input tt-lookup-qry-name,
       output tt-ql-hdl).
   p-query = tt-ql-hdl.
END PROCEDURE.
PROCEDURE get-query-field-list :
/*------------------------------------------------------------------------------
  Purpose:     To return the concatenated field list for generating the query.
  Parameters:  input p-table: character: name of table
               output p-field-list: character: parenthesized list of fields
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id   as character no-undo.
   define input  parameter p-table       as character no-undo.
   define output parameter p-field-list  as character no-undo.
   run establish-context
      (input p-browse-id).
   for each tt-browse-field of tt-browse-mstr where (tt-table-name = p-table):
      p-field-list = p-field-list +
                     (if p-field-list = "" then "" else " ") +
                     tt-browse-field.tt-field-name.
   end.
   p-field-list = "(" + p-field-list + ")".
END PROCEDURE.
PROCEDURE get-query-handle :
/*------------------------------------------------------------------------------
  Purpose:     To return the persistent procedure handle for the designated
               query of the specified browse.
  Parameters:  input p-browse-id: character: browse name
               input p-query-type: character: "FILT", "UNFILT", "LOOKUP"
               output p-query-hdl: handle: handle to query
  Notes:       This will return the current value for the handle even if it's
               null.  It is up to the requesting process to test the return value
               and to start a query (with the appropriate parameters) if it needs one.
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id  as character no-undo.
   define input  parameter p-query-type as character no-undo.
   define output parameter p-query-hdl  as handle    no-undo.
   run establish-context
      (input p-browse-id).
   case p-query-type:
      when "FILT"   then p-query-hdl = tt-browse-mstr.tt-qf-hdl.
      when "UNFILT" then p-query-hdl = tt-browse-mstr.tt-qr-hdl.
      when "LOOKUP" then p-query-hdl = tt-browse-mstr.tt-ql-hdl.
   end case.
END PROCEDURE.
PROCEDURE get-table-ldb :
/*------------------------------------------------------------------------------
  Purpose:     Find the logical db name, this is needed for multi-db
  Parameters:  input  p-table: character: table name
               output p-ldb:   character: logical db name
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-table  as character no-undo.
   define output parameter p-ldb    as character no-undo.
   define variable dbi              as integer   no-undo.
   {gpfilev.i}
   {gpfilpre.i &file_name=p-table}
   if file_found then do:
      /*db_string is a list of all connected ldbnames.          */
      /*db_point is a counter that cycles through db_string     */
      /*returning file_found if the table name matches the entry*/
      assign p-ldb = entry(db_point,db_string).
      /* The following statement generates an Oracle standards warning. */
      /* This is a known, acceptable violation of the standards.        */
      do dbi = 1 to num-dbs :
         if sdbname(dbi) = p-ldb and ldbname(dbi) <> sdbname(dbi) then
           assign p-ldb = ldbname(dbi).
      end.
   end.
END PROCEDURE.
PROCEDURE look-for-code :
/*------------------------------------------------------------------------------
  Purpose:
  Parameters:  input p-ui-type: character: says if we're dealing with browse
                or lookup or printer
               output p-local-rcode:  logical: found rcode in working directory
               output p-local-pcode:  logical: found pcode in working directory
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-ui-type      as character no-undo.
   define output parameter p-local-rcode  as logical   no-undo.
   define output parameter p-local-pcode  as logical   no-undo.
   define variable c-pcode-name as character no-undo.
   define variable c-rcode-name as character no-undo.
   case p-ui-type:
      when "POWER"   then c-pcode-name   = tt-browse-mstr.tt-br-ui-name.
      when "LOOKUP"  then c-pcode-name   = tt-browse-mstr.tt-lu-ui-name.
      when "PRINTER" then c-pcode-name   = tt-browse-mstr.tt-pr-ui-name.
      when "GRAPH"   then c-pcode-name   = tt-browse-mstr.tt-gr-ui-name.
   end case.
   assign
      c-rcode-name  = substring(c-pcode-name, 1, index(c-pcode-name, ".")) + "r"
      p-local-rcode = search(c-rcode-name) <> ?
      p-local-pcode = search(c-pcode-name) <> ?.
END PROCEDURE.
PROCEDURE lu-shutdown :
/*------------------------------------------------------------------------------
  Purpose:     To shutdown all pieces of terminating Lookup
  Parameters:  p-lookup-id: character: name of lookup that is shutting down.
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-lookup-id as character no-undo.
   assign filter-logic = "".
   run establish-context
      (input p-lookup-id).
   run purge-all-files
     (input p-lookup-id).
   if valid-handle(tt-browse-mstr.tt-ql-hdl) then do:
      run close-query in tt-ql-hdl.
      delete procedure tt-ql-hdl.
   end.
   if available(tt-browse-mstr) then
      run removettBrowseMstr
         (input tt-browse-mstr.tt-browse,
          input tt-browse-mstr.tt-cparm1,
          input tt-browse-mstr.tt-cparm2,
          input tt-browse-mstr.tt-cparm3,
          input tt-browse-mstr.tt-cparm4,
          input tt-browse-mstr.tt-cparm5,
          input tt-browse-mstr.tt-nparm1,
          input tt-browse-mstr.tt-nparm2,
          input tt-browse-mstr.tt-dparm1,
          input tt-browse-mstr.tt-dparm2).
   if keyfunction(lastkey) = "END-ERROR" then
      run q-chk-additional-lu
         (input p-lookup-id).
END PROCEDURE.
PROCEDURE purge-all-files :
/*------------------------------------------------------------------------------
  Purpose:     To remove all source code files created during the life of this
               procedure.
  Parameters:  p-browse-id
  Notes:       Modified 8/14/97 by JPM to delete browse def each time from temp
               table. If this is not done, the global variables do not get set
               properly when the source code is created.
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   for each tt-file of tt-browse-mstr:
      /*Do not delete BR & LU files*/
      if  substring(tt-file,3,2) <> "BR" and
          substring(tt-file,3,2) <> "LU" then do:
          os-delete value(tt-filename).
          os-delete value(tt-rcode).
      end.
   end.
   /* Delete browse definition */
   for first tt-browse-mstr where tt-browse-mstr.tt-browse = p-browse-id : end.
   if available(tt-browse-mstr) then do:
      /* Delete context of browse fields*/
      for each tt-browse-field
         where tt-browse-field.tt-browse = tt-browse-mstr.tt-browse
      exclusive-lock:
         delete tt-browse-field.
      end.
      /* Delete context of browse files*/
      for each tt-file
         where tt-file.tt-browse = tt-browse-mstr.tt-browse
      exclusive-lock:
         delete tt-file.
      end.
   end.
END PROCEDURE.
PROCEDURE q-chk-additional-lu :
/*------------------------------------------------------------------------------
  Purpose:     Check to see if there is an END-ERROR lu attached to run
  Parameters:  p-lookup-id: character: name of lookup that is shutting down.
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-lookup-id as character no-undo.
   define variable l-is-browse as logical   no-undo.
   define variable c-browse-id as character no-undo.
   define variable c-call-pgm  as character format "x(10)" no-undo.
   /* Create filename (*lu*.p)*/
   c-call-pgm = substring(p-lookup-id, 1, 2, "RAW") + "lu" +
                substring(p-lookup-id, 3, 4, "RAW")   + ".p".
   for first flh_mstr
      where flh_mstr.flh_field = "END-ERROR"
      and   flh_mstr.flh_call  = c-call-pgm
   no-lock:
      if flh_exec <> c-call-pgm then do:
         assign
            l-is-browse = (index(flh_exec, "lu") = 3) and not error-status:error
            c-browse-id = substring(flh_exec, 1, 2, "RAW") +
                          substring(flh_exec, 5, 3, "RAW").
         if l-is-browse then
            run run-lookup
               (input c-browse-id,
                output swindow_recid).
      end.
   end.
END PROCEDURE.
PROCEDURE q-get-column-info :
/*------------------------------------------------------------------------------
  Purpose:     Gets info for each column of the browse
  Parameters:  input p-browse-id: id of browse
               output p-col-info: delimited list of column labels, etc.
  Notes:       Returns a list of lists.
               Column info consists of the:
                    label, data-type, format, name, and column-label
               for each (up to 20) columns
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id  as character no-undo.
   define output parameter p-col-labels as character no-undo.
   define variable i         as integer   no-undo.
   define variable c-ci-list as character no-undo.
   define variable l_ttlabel as character no-undo.
   run establish-context
      (input p-browse-id).
   p-col-labels = fill({&COL-DELIM}, tt-browse-mstr.tt-num-fields - 1).
   for each tt-browse-field of tt-browse-mstr:
      assign
         i = i + 1
         c-ci-list = fill({&CI-DELIM}, {&CI-COLUMN-LABEL} - 1).
      /* IF THE BROWSE FIELD LABEL CONTAINS AN UNKNOWN VALUE       */
      /* OR BLANK VALUE THEN THE VALUE OF FIELD NAME IS ASSIGNED   */
      /* c-ci-list SO THAT c-ci-list DOES NOT GET SET TO A         */
      /* UNKNOWN OR BLANK VALUE                                    */
      if tt-browse-field.tt-label <> "" and tt-browse-field.tt-label <> ?
      then
         l_ttlabel =  tt-browse-field.tt-label.
      else
         l_ttlabel =  tt-browse-field.tt-field-name.
      assign
         entry({&CI-LABEL},c-ci-list, {&CI-DELIM}) = l_ttlabel
         entry({&CI-DATA-TYPE},c-ci-list, {&CI-DELIM}) = tt-browse-field.tt-datatype
         entry({&CI-FORMAT},c-ci-list, {&CI-DELIM}) = tt-browse-field.tt-format
         entry({&CI-NAME},c-ci-list, {&CI-DELIM}) = tt-browse-field.tt-field-name
         entry({&CI-COLUMN-LABEL}, c-ci-list,{&CI-DELIM}) = l_ttlabel
         entry(i, p-col-labels, {&COL-DELIM}) = c-ci-list.
   end.
END PROCEDURE.
PROCEDURE q-get-criteria :
/*------------------------------------------------------------------------------
  Purpose:     Returns delimited lists of field, label, type and format info
  Parameters:  input  p-browse-id: name of browse
               output p-br-flds: delimited list of field names
               output p-br-labs: delimited list of field labels
               output p-br-type: delimited list of datatypes
               output p-br-fmts: delimited list of formats
               output p-br-vals: number of filter variables
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character            no-undo.
   define output parameter p-br-flds   as character initial "" no-undo.
   define output parameter p-br-labs   as character initial "" no-undo.
   define output parameter p-br-type   as character initial "" no-undo.
   define output parameter p-br-fmts   as character initial "" no-undo.
   define output parameter p-br-vals   as integer   initial 0  no-undo.
   define variable i-cnt as integer   no-undo.
   define variable c-fmt as character no-undo.
   define variable l_ttlabel as character no-undo.
   run establish-context
      (input p-browse-id).
   for each tt-browse-field of tt-browse-mstr:
      assign i-cnt = i-cnt + 1.
      {gpappend.i p-br-flds tt-field-name}
      {gpappend.i p-br-type tt-datatype}
      /* IF THE BROWSE FIELD LABEL CONTAINS AN UNKNOWN OR BLANK */
      /* VALUE THEN p-br-labs IS ASSIGNED THE VALUE IN BROWSE   */
      /* FIELD NAME TO PREVENT IT FROM BEING SET TO A UNKNOWN   */
      /* VALUE                                                  */
      if tt-label <> "" and tt-label <> ?
      then
         l_ttlabel = tt-label.
      else
         l_ttlabel = tt-field-name.
      {gpappend.i p-br-labs l_ttlabel}
      /*Added this to handle integers and decimals low values in the filter*/
      if (tt-datatype = "INTEGER" or tt-datatype = "DECIMAL") and
         index(tt-format,"-") = 0 and index(tt-format,"CR") = 0
      then
         c-fmt = "-" + tt-format.
      else
         c-fmt = tt-format.
      if c-fmt = "" then do:
         if tt-datatype = "INTEGER" or tt-datatype = "RECID" then
            c-fmt = "->>>>>>>".
         else if tt-datatype = "DECIMAL" then
            c-fmt = "->>>>>>>.<<".
         else if tt-datatype = "CHARACTER" then
            c-fmt = "x(8)".
         else if tt-datatype = "DATE" then
             c-fmt = "99/99/99".
         else if tt-datatype = "LOGICAL" then
             c-fmt = "yes/no".
      end. /* if c-fmt = "" */
      {gpappend.i p-br-fmts c-fmt """" ""|""}
   end.
   p-br-vals = i-cnt.
END PROCEDURE.
PROCEDURE q-get-field-criteria :
/*------------------------------------------------------------------------------
  Purpose:     To get the attributes of a particular column
  Parameters:  input p-browse-id: character: browse id
               input p-column   : integer  : which column
               output p-label   : character: label of column
               output p-type    : character: data-type
               output p-format  : character: display format of column
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character no-undo.
   define input  parameter p-column    as integer   no-undo.
   define output parameter p-name      as character no-undo.
   define output parameter p-label     as character no-undo.
   define output parameter p-type      as character no-undo.
   define output parameter p-format    as character no-undo.
   run establish-context
      (input p-browse-id).
   for first tt-browse-field of tt-browse-mstr
   where tt-seq = p-column : end.
   if available(tt-browse-field) then do:
      assign
         p-name   = tt-field-name
         p-label  = tt-label
         p-type   = tt-datatype
         p-format = tt-format.
   end.
END PROCEDURE.
PROCEDURE remove-context :
/*------------------------------------------------------------------------------
  Purpose:     To remove the context of the browse
  Parameters:  p-browse-id  character browse name to be removed from temp tables
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   run establish-context
      (input p-browse-id).
   run remove-file
      (input p-browse-id).
   do transaction:
      for first tt-browse-mstr where tt-browse = p-browse-id : end.
      if available(tt-browse-mstr) then do:
         /* Delete context of browse fields*/
         for each  tt-browse-field
             where tt-browse-field.tt-browse = tt-browse-mstr.tt-browse
         exclusive-lock:
            delete tt-browse-field.
         end.
         /* Delete context of browse files*/
         for each  tt-file
             where tt-file.tt-browse = tt-browse-mstr.tt-browse
         exclusive-lock:
            delete tt-file.
         end.
         /*Delete the browse master reference*/
         delete tt-browse-mstr.
      end.
   end.
END PROCEDURE.
PROCEDURE remove-file :
/*------------------------------------------------------------------------------
  Purpose:     To remove a specific source code file
  Parameters:  p-filename: character: name of file to be removed
  Notes:       Assumes that the context (of the browse or lookup) has already
               been established.
------------------------------------------------------------------------------*/
   define input parameter p-filename as character no-undo.
   for first tt-file where tt-file.tt-browse = tt-browse-mstr.tt-browse
      and tt-filename = p-filename : end.
   if available(tt-file) then do:
      os-delete value(tt-filename).
      os-delete value(tt-rcode).
      delete tt-file.
   end.
END PROCEDURE.
PROCEDURE run-lookup :
/*------------------------------------------------------------------------------
  Purpose:     To find (create, if necessary) and run the given lookup
  Parameters:  
  Notes:
------------------------------------------------------------------------------*/
   define input  parameter p-lookup-id as character no-undo.
   define output parameter tmp-recid   as recid     no-undo.
   define variable c-other-id          as character no-undo.
    run findBranchBrowse
       (input p-lookup-id,
        output c-other-id).
   if c-other-id <> "" then
      p-lookup-id = c-other-id.
   run establish-context
      (p-lookup-id).
   run activate-ui
      (input "LOOKUP").
   tmp-recid = swindow_recid.
END PROCEDURE.
PROCEDURE shutdown-browse :
/*------------------------------------------------------------------------------
  Purpose:     To close all persistent procedures opened by the generator
               (for this browse)
  Parameters:  p-browse-id: character: name of the browse to terminate
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   assign filter-logic = "".
   run establish-context
      (input p-browse-id).
   if valid-handle(tt-browse-mstr.tt-br-hdl) then do:
      delete procedure tt-br-hdl.
      assign tt-br-hdl = ?.
   end.
   if valid-handle(tt-browse-mstr.tt-qr-hdl) then do:
      run close-query in tt-qr-hdl.
      delete procedure tt-qr-hdl.
      assign tt-qr-hdl = ?.
   end.
   if valid-handle(tt-browse-mstr.tt-qf-hdl) then do:
      run close-query in tt-qf-hdl.
      delete procedure tt-qf-hdl.
      assign tt-qf-hdl = ?.
   end.
   if valid-handle(tt-browse-mstr.tt-pr-hdl) then do:
      delete procedure tt-pr-hdl.
      assign tt-pr-hdl = ?.
   end.
   if valid-handle(tt-browse-mstr.tt-gr-hdl) then do:
      delete procedure tt-gr-hdl.
      assign tt-gr-hdl = ?.
   end.
   if valid-handle(tt-browse-mstr.tt-qg-hdl) then do:
      delete procedure tt-qg-hdl.
      assign tt-qg-hdl = ?.
   end.
   run purge-all-files
      (input p-browse-id).
   /* Delete tt-browse-mstr record */
   if available(tt-browse-mstr) then
      run removettBrowseMstr
         (input tt-browse-mstr.tt-browse,
          input tt-browse-mstr.tt-cparm1,
          input tt-browse-mstr.tt-cparm2,
          input tt-browse-mstr.tt-cparm3,
          input tt-browse-mstr.tt-cparm4,
          input tt-browse-mstr.tt-cparm5,
          input tt-browse-mstr.tt-nparm1,
          input tt-browse-mstr.tt-nparm2,
          input tt-browse-mstr.tt-dparm1,
          input tt-browse-mstr.tt-dparm2).
END PROCEDURE.
PROCEDURE substitute-globals :
/*------------------------------------------------------------------------------
  Purpose:     To replace uses of globals with their current values
  Parameters:  p-str: char that may contain reference to a global.
  Notes:       this obviates the use of mfdeclre in generated queries
------------------------------------------------------------------------------*/
   define input-output parameter p-str as character no-undo.
   define variable i      as integer   no-undo.
   define variable i-st   as integer   no-undo.
   define variable i-len  as integer   no-undo.
   define variable c-name as character no-undo.
   define variable c-val  as character no-undo.
   define variable i-lb   as integer   no-undo.   /* location of left-bracket */
   define variable i-rb   as integer   no-undo.   /* location of right-bracket */
   define variable i-idx  as integer   no-undo.   /* value of index */
   define variable k-globals as character
      initial "GLOBAL_PART,GLOBAL_SITE,GLOBAL_LOC,GLOBAL_ADDR,GLOBAL_USER_LANG,GLOBAL_USERID,STSTATUS,GLOBAL_REF,GLOBAL_LOT,GLOBAL_TYPE,GLOBAL_LANG,STLINE" no-undo.
   do i = 1 to num-entries(k-globals):
      assign
         c-name = entry(i, k-globals)
         i-st = index(p-str, c-name).
      do while i-st > 0 :
         assign i-len = length(c-name, "RAW").
         case c-name:
            when "GLOBAL_PART" then      assign c-val = global_part.
            when "GLOBAL_SITE" then      assign c-val = global_site.
            when "GLOBAL_LOC" then       assign c-val = global_loc.
            when "GLOBAL_ADDR" then      assign c-val = global_addr.
            when "GLOBAL_USER_LANG" then assign c-val = global_user_lang.
            when "GLOBAL_USERID" then    assign c-val = global_userid.
            when "STSTATUS" then         assign c-val = ststatus.
            when "GLOBAL_REF" then       assign c-val = global_ref.
            when "GLOBAL_LOT" then       assign c-val = global_lot.
            when "GLOBAL_TYPE" then      assign c-val = global_type.
            when "GLOBAL_LANG" then      assign c-val = global_lang.
            when "STLINE" then do:  /* known to have an extent */
               assign
                  i-lb  = index(p-str, "[", i-st)
                  i-rb  = index(p-str, "]", i-lb)
                  i-idx = integer(substring(p-str, i-lb + 1, (i-rb - i-lb) - 1))
                  i-len = i-len + (i-rb - i-lb) + 1
                  c-val = stline[i-idx].
             end.
         end case.
         /* Replace each occurrence of double quotes (") by adding */
         /* another double quote (") after the respective variable */
         /* values are assigned to c-val.                          */
         assign
            c-val = replace(c-val,'"','""')
            substring(p-str, i-st, i-len, "RAW") = chr(34) + c-val + chr(34)
            i-st = index(p-str, c-name).  /* look again for same string */
      end.
   end.
END PROCEDURE.
PROCEDURE update-parm :
/*------------------------------------------------------------------------------
  Purpose:     To implement run-time parameters for use in lookups and browses
  Parameters:  p-str: char that may contain reference to a global.
  Notes:       This obviates the use of mfdeclre in generated queries
------------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   define input parameter p-parm      as character no-undo.
   define input parameter p-value     as character no-undo.
   /* REPLACE EACH OCCURRENCE OF DOUBLE QUOTES (") BY ADDING */
   /* ANOTHER DOUBLE QUOTES (") IN input PARAMETER p-value.  */
   p-value = replace(p-value,'"','""').
   run establish-context
      (input p-browse-id).
   case p-parm:
      when "c-brparm1" then assign tt-browse-mstr.tt-cparm1 = p-value.
      when "c-brparm2" then assign tt-browse-mstr.tt-cparm2 = p-value.
      when "c-brparm3" then assign tt-browse-mstr.tt-cparm3 = p-value.
      when "c-brparm4" then assign tt-browse-mstr.tt-cparm4 = p-value.
      when "c-brparm5" then assign tt-browse-mstr.tt-cparm5 = p-value.
      when "n-brparm1" then assign tt-browse-mstr.tt-nparm1 = decimal(p-value).
      when "n-brparm2" then assign tt-browse-mstr.tt-nparm2 = decimal(p-value).
      when "d-brparm1" then assign tt-browse-mstr.tt-dparm1 = date(p-value).
      when "d-brparm2" then assign tt-browse-mstr.tt-dparm2 = date(p-value).
      when "l-brparm1" then do:
         if p-value = "yes" or p-value = "true" then
            assign tt-browse-mstr.tt-lparm1 = true.
         else
            assign tt-browse-mstr.tt-lparm1 = false.
      end.
      when "l-brparm2" then do:
         if p-value = "yes" or p-value = "true" then
            assign tt-browse-mstr.tt-lparm2 = true.
         else
            assign tt-browse-mstr.tt-lparm2 = false.
      end.
   end case.
END PROCEDURE.
PROCEDURE verify-ldbs :
/*------------------------------------------------------------------------------
  Purpose:     To verify the tt-ldb[i] value reflects the current connected
               logical db name.
  Parameters:  none.
  Notes:
------------------------------------------------------------------------------*/
   define variable c-ldb as character no-undo.
   define variable i     as integer   no-undo.
   /* Always need to verify the connected DB for the query*/
   /* Get the first logical db name for the table.*/
   /* Needed for multi-db's*/
   if available tt-browse-mstr then do:
      do i = 1 to tt-browse-mstr.tt-num-tables:
         if tt-browse-mstr.tt-table[i] <> "" then do:
            run get-table-ldb
               (input tt-browse-mstr.tt-table[i],
                output c-ldb).
            assign tt-browse-mstr.tt-l-db[i] = c-ldb.
         end.
      end.
   end.
END PROCEDURE.
PROCEDURE write-file-header :
/*------------------------------------------------------------------------------
  Purpose:     To provide a single parameterized file header
  Parameters:  p-filename: character: name of file
               p-type:     character: type of file (UI, Query, Lookup, ...)
  Notes:
------------------------------------------------------------------------------*/
   define input parameter p-filename as character no-undo.
   define input parameter p-type     as character no-undo.
   define input parameter p-eco-nbr  as character no-undo.
   define variable   i             as integer   no-undo.
   define variable   c-eco-nbr     as character no-undo.
   define variable   c-use-history as character no-undo.
   define variable   c-scop        as character no-undo
      initial "~&SCOPED-DEFINE ".
   define variable   file-no-ext   as character no-undo.
   define variable   prog-name     as character no-undo.
   /* Relocate logic from MAIN BLOCK so it is more accurate*/
   /* Only write History information if the cfdb (and prol_det) is connected*/
   assign
      c-eco-nbr = p-eco-nbr
      c-use-history = "no".
   if connected("qadadm") then
      assign c-use-history = "yes".
   put unformatted
      "/* " + p-filename + " - " +
          string(tt-browse-mstr.tt-description + " " + p-type,"x(61)") +  "*/"
      skip
      "/* Copyright 1986-" + string(year(today)) +
         " QAD Inc., Carpinteria, CA, USA.                      */"
      skip
      "/* All rights reserved worldwide.  This is an unpublished work.             */"
      skip
      "/* ~$Revision: 1.71.1.5 $    */"
      skip
      "/*V8:ConvertMode=NoConvert                                                  */"
      skip.
   put unformatted
      "/********************************** History *********************************"
      skip.
   if c-use-history = "yes" then do on error undo, leave:
      {gprun.i 'gpbrhist.p'
                "(input tt-browse-mstr.tt-browse,
                  input 'history')"}
   end.
   put unformatted
      " ****************************************************************************/"
      skip(1).
END PROCEDURE.
PROCEDURE getLookupParameters:
 /* ----------------------------------------------------------------------------
  Purpose      : Retrieve lookup parameters from the tt-browse-mstr
                 temp table.
  Parameters   : bufferHandle - a handle to a temp-table that will
                                be populated with the lookup
                                parameters.
  Notes        : This will add records to the temp-table pointed to by the
                 input parameter 'bufferHandle'. This procedure does not care
                 what temp-table 'bufferHandle' points to. It only cares that
                 the first 6 fields of that temp-table are character fields.
                 This will create a record in the input temp-table for each
                 tt-browse-mstr record that exists and is a lookup. The
                 input temp-table will be populated as follows:
                 temp-table field 1 = lookup name
                 temp-table field 2 = lookup parameter 1 (tt-cparm1)
                 temp-table field 3 = lookup parameter 2 (tt-cparm2)
                 temp-table field 4 = lookup parameter 3 (tt-cparm3)
                 temp-table field 5 = lookup parameter 4 (tt-cparm4)
                 temp-table field 6 = lookup parameter 5 (tt-cparm5)
 -----------------------------------------------------------------------------*/
   define input parameter bufferHandle as handle no-undo.
   define variable fieldHandle as handle no-undo.
   for each tt-browse-mstr no-lock where tt-lookup = yes:
      bufferHandle:buffer-create().
      assign
         fieldHandle = bufferHandle:buffer-field(1)
         fieldHandle:buffer-value = tt-lu-ui-name
         fieldHandle = bufferHandle:buffer-field(2)
         fieldHandle:buffer-value = tt-cparm1
         fieldHandle = bufferHandle:buffer-field(3)
         fieldHandle:buffer-value = tt-cparm2
         fieldHandle = bufferHandle:buffer-field(4)
         fieldHandle:buffer-value = tt-cparm3
         fieldHandle = bufferHandle:buffer-field(5)
         fieldHandle:buffer-value = tt-cparm4
         fieldHandle = bufferHandle:buffer-field(6)
         fieldHandle:buffer-value = tt-cparm5.
   end.
END PROCEDURE.
PROCEDURE removeLookupContext:
 /* ----------------------------------------------------------------------------
  Purpose: Remove the context for all the lookups
 -----------------------------------------------------------------------------*/
   for each tt-browse-mstr no-lock where tt-lookup = yes:
      run remove-context (input tt-browse).
   end.
END PROCEDURE.
PROCEDURE removettBrowseMstr:
 /* ----------------------------------------------------------------------------
  Purpose: Delete the tt-browse-mstr record, then recreate is any of the
           local parameters are set.
 -----------------------------------------------------------------------------*/
   define input parameter p-browse-id as character no-undo.
   define input parameter local-cparm1 as character no-undo.
   define input parameter local-cparm2 as character no-undo.
   define input parameter local-cparm3 as character no-undo.
   define input parameter local-cparm4 as character no-undo.
   define input parameter local-cparm5 as character no-undo.
   define input parameter local-nparm1 as decimal no-undo.
   define input parameter local-nparm2 as decimal no-undo.
   define input parameter local-dparm1 as date no-undo.
   define input parameter local-dparm2 as date no-undo.
   delete tt-browse-mstr.
   if local-cparm1 <> "" then
      run update-parm
         (input p-browse-id, input "c-brparm1", input local-cparm1).
   if local-cparm2 <> "" then
      run update-parm
         (input p-browse-id, input "c-brparm2", input local-cparm2).
   if local-cparm3 <> "" then
      run update-parm
         (input p-browse-id, input "c-brparm3", input local-cparm3).
   if local-cparm4 <> "" then
      run update-parm
         (input p-browse-id, input "c-brparm4", input local-cparm4).
   if local-cparm5 <> "" then
      run update-parm
         (input p-browse-id, input "c-brparm5", input local-cparm5).
   if local-nparm1 <> 0 then
      run update-parm
         (input p-browse-id, input "n-brparm1", input string(local-nparm1)).
   if local-nparm2 <> 0 then
      run update-parm
         (input p-browse-id, input "n-brparm2", input string(local-nparm2)).
   if local-dparm1 <> ? then
      run update-parm
         (input p-browse-id, input "d-brparm1", input string(local-dparm1)).
   if local-dparm2 <> ? then
      run update-parm
         (input p-browse-id, input "d-brparm2", input string(local-dparm2)).
END PROCEDURE.
PROCEDURE findBranchBrowse:
/*----------------------------------------------------------------------------
  Purpose: Decide if a different lookup needs to be run
 -----------------------------------------------------------------------------*/
   define input  parameter p-browse-id as character.
   define output parameter p-other-id  as character.
   define variable c-lu-name           as character no-undo.
   define variable i-id                as integer no-undo.
   define buffer qadwkfl for qad_wkfl.
   p-other-id = "".
   c-lu-name = substring(p-browse-id,1,2,"RAW") + "lu" +
               substring(p-browse-id,3,4,"RAW") + ".p".
   find first qadwkfl where
      qad_key1 = mfguser + "Lookup" and
      qad_key2 = c-lu-name
   no-lock no-error.
   if available qadwkfl then do:
      c-lu-name = qadwkfl.qad_charfld[1].
      i-id = integer(substring(c-lu-name,5,3,"RAW")) no-error.
      if (index(c-lu-name,"lu") = 3) and
            not error-status:error
      then
         p-other-id = substring(c-lu-name,1,2,"RAW") +
                      substring(c-lu-name,5,3,"RAW").
   end. /* if available */
END PROCEDURE.
      
 
